大数据分析Python生成器使用教程
时间:2020-09-17来源:www.aaa-cg.com.cn点击量:次作者:Sissi
时间:2020-09-17点击量:次作者:Sissi
Python生成器是一个功能强大但被误解的工具。对于初学者来说,他们通常被认为是一个过于困难的概念,从而产生了一种幻象,即初学者应该在学习generator生成器之前一直坚持不懈,直到他们准备好为止。我认为这种评估是不公平的,您可以比您想象的更早使用generator生成器。在大数据分析Python生成器使用教程中,我们将介绍:
1)了解生成器所需的基本术语
2)什么是generator生成器
3)如何创建自己的generator生成器
4)如何使用生成器和生成器方法
5)何时使用generator生成器
先决条件
为了充分利用大数据分析Python生成器使用教程,您应该熟悉以下概念:
1)基本的Python数据结构
a)什么是清单
b)什么是字典
2)功能
a)什么是功能
b)如何创建和使用功能
3)清单理解
a)什么是列表理解
b)如何创建一个简单的列表理解
基本术语
迭代和可迭代
迭代是一遍又一遍地重复某种过程。Python的for循环为我们提供了一种遍历各种对象的简便方法。通常,您会遍历一个列表,但是我们也可以遍历其他Python对象,例如字符串和字典。
在以上每个示例中,for循环遍历我们给出的序列。上面的代码使用了列表,字符串和字典,但是您也可以遍历元组和集合。在上面的每个循环中,我们print按顺序显示序列中的每个项目。例如,您可以确认的顺序ez_list已按照其项目的打印顺序进行复制。
我们将可以支持迭代的任何对象称为可迭代。
什么定义了迭代?
可迭代支持一种称为
迭代器协议。Iterator协议的技术定义不在大数据分析Python生成器使用教程的讨论范围之内,但是可以将其视为用于循环的一组要求for。也就是说:列表,字符串和字典都遵循Iterator协议,因此我们可以在for循环中使用它们。相反,不能遵循该协议的对象不能在for循环中使用。不遵循该协议的对象的一个示例是整数。如果我们尝试将整数赋予for循环,Python将抛出错误。
整数只是一个单数,而不是一个序列。您可能会争辩说,number为1,但与序列中的第一个项目不同。问“ 1之后是什么?”是没有意义的。从number因为Python既懂整数作为一个单一的实体。因此,可迭代的要求之一是能够向for循环描述执行操作的下一项是什么。例如,列表告诉for循环,要迭代的下一项在当前项的索引+1中(1在0之后)。因此,迭代器还必须for在停止时向循环发出信号迭代。当我们到达序列的末尾(即列表或字符串的末尾)时,通常会出现此信号。在大数据分析Python生成器使用教程的后面,我们将探讨使某些事物可迭代的特定函数,要知道的重要一点是,可迭代对象描述了循环应如何for遍历其内容。生成器本身就是可迭代的。稍后您将看到,for循环是我们使用生成器的主要方式之一,因此循环必须能够支持迭代。我们将深入研究如何在下一秒创建自己的生成器。
关键要点:要了解的基本术语
1)迭代是在一系列项目上重复某些过程的想法。在Python中,迭代通常与for循环有关。
2)可迭代对象是支持迭代的对象。
3)要进行迭代,它必须向for循环描述两件事:
a)迭代中的下一个项目是什么。
b)循环何时应停止迭代。
4)生成器是可迭代的。
基于数据的方法
为了真正探索generator生成器,我们将使用
来自Kaggle的Brewer's Friend Beer Recipes数据集。如果您想在自己的计算机上继续学习,可以在这里找到数据集。数据包含来自世界各地啤酒商的重要啤酒特性,包括啤酒样式,酒精含量(ABV)和啤酒产量。就大数据分析Python生成器使用教程而言,假设我们对酿造自己的啤酒感兴趣。也许我们想出售我们的啤酒,所以我们想看看其他人做了些什么,以告知我们的酿造选择并生产更多流行的啤酒样式。作者注:原始数据集中的“名称”列包含一些凌乱的值,这些值会干扰我们的分析。您可以在此处找到可以满足我们目的的清理版本。
generator生成器和你
如果您以前从未遇到过generator生成器,那么现实中最常见的generator生成器示例就是备用generator生成器,它会创建-
发电 —为您的房屋或办公室供电。从概念上讲,Python生成器从给定的序列一次生成一个值,而不是一次给出整个序列。生成器的这种一次性方式使它们与for循环如此兼容。如果这听起来令人困惑,请不要担心太多。当我们解释如何创建生成器时,它将变得更加清晰。有两种创建生成器的方法。它们的语法不同,但是最终结果仍然是生成器。我们将通过覆盖这些语法并将它们与类似但非生成器等效的语法进行比较,来教授这些概念。
1)生成器函数与常规函数
2)生成器表达式与列表理解
generator生成器功能
生成器函数就像常规函数一样,但是有一个关键的区别:
yield关键字替换return。
上面的两个函数执行完全相同的操作(返回/产生相同的字符串)。但是,如果您尝试检查生成器功能,它将与常规功能显示的内容不匹配。
调用常规函数会告诉Python返回该函数在我们代码中的位置,在代码块中执行代码,然后返回结果。为了使生成器函数产生其值,您需要将其传递给
next()功能。next()是一个特殊的函数,询问“迭代中的下一个项目是什么?” 实际上,next()是运行for循环时调用的精确函数!列表,字典,字符串等都实现了next(),因此这就是为什么您可以首先将它们合并到循环中的原因。
注意,由于函数本身就是生成器,因此必须在生成器函数中加上括号。仅提供函数名称会引发错误,因为您尝试提供
next()函数名称。不出所料,yield一旦调用next()函数,生成器函数将为“ a” 。此示例不能完全代表生成器的用途。请记住,生成器会生成一个值流,因此,yield单个值实际上并没有资格作为流。为此,我们实际上可以将多个yield语句放入生成器函数中。这些yield语句构成了生成器将输出的顺序。我们将创建一个生成器并将其绑定到一个varible mg。然后,如果我们继续mg进入next(),我们将进入下一个yield。如果我们继续前进,将被告知StopIteration错误,告知生成器没有其他值可提供。该StopIteration错误实际上是一个如何for 循环知道何时停止迭代。
分配
multi_generate到mg在使用generator生成器功能的关键步骤。将生成器绑定到mg允许我们创建可以参考的生成器的单个实例。我们可以继续传递mg到next()并获得与其他yield语句。观察如果我们继续尝试自己传递下去会发生什么multi_generate。
容易将生成器视为仅等待一个命令和一个命令的机器:
next()。调用next()生成器后,它将按其持有的顺序分配下一个值。否则,您将无法使用生成器执行其他任何操作。下图将我们的generator生成器表示为一台简单的机器。
我们继续得到第一条yield陈述的结果。其背后的原因是微妙的。当我们将生成器函数本身传递给时next(),Python会假定您正在向其中传递一个新实例multi_generate,因此它将始终为您提供第一个yield结果。通过将生成器绑定到变量,Python知道在将其传递给时,您正在尝试对同一件事采取行动next()。我们注意到,随着我们不断传递mg下一个,我们得到了其他yield结果。仅当生成器以某种方式记住其上次执行的操作时,这才有可能。该存储器是生成器功能与常规功能的区别!使用函数后,这是一项一劳永逸的交易。一旦您return该函数的值。生成器将保留yield值直到输出。这带给我们generator生成器的另一个重要特性。一旦完成对它们的遍历,就不能再使用它们了。一旦我们了解了中的所有三个yield值mg,便无法再为我们提供任何东西。我们必须存储multi_generate生成器的另一个实例,以next()再次开始询问它的语句。我们的数据尚未被读取,因此让我们使用生成器函数来完成。数据称为recipeData.csv,并且包含在CSV文件中。我们将使用该open()函数使我们能够读取它,并且我们将开始使用该next()函数来读取CSV的前几行。
我们将慢慢剖析上面的代码:
1)我们已指定dataGenerator生成器作为生成器函数,它将逐行分配CSV文件。该函数在中包含文件名file,这使我们能够使用该open()函数读取文件。
2)虽然我们讨论了可以迭代列表和字典之类的Python对象,但是我们也可以迭代文件open()。
3)该encoding通知的Python应该期望看到什么样的角色; ISO-8859-1特别是指Latin-1。
4)该for循环将在CSV文件的第一行,启动yield该行,然后保存当前发生在阅读文件,直到生成函数被再次调用。
如果要在自己的计算机上跟踪数据,则需要更换
file以及计算机上文件所在位置的确切路径。这将使Python可以在需要时找到open()它。
一旦我们创建了一个
beerDataGenerator生成器在中beer,我们可以开始将其传递next()来查看数据本身。如CSV文件所建议的,这些列用逗号分隔。此外,每行以结束\n,表示换行。我们发现,其中的第一项recipeData.csv是列名列表,第一行描述了美味的香草奶油啤酒。
自我施加的限制
您可能会问:“我们可以将数据存储在列表理解中!为什么要跳一个额外的箍并使用generator生成器?” 作为程序员,您可能会遇到
大数据。这是一个模糊的术语,因此在这里我们不会深入研究各种大数据定义。可以说任何大数据文件太大分配给变量。我们的数据文件不符合大数据的条件,但是我们仍然可以通过限制自己来重新创建这个难题来学到很多东西。现在,我们假定啤酒数据量太大,以至于我们无法将所有数据存储在列表中。由于无法正常读取数据,因此我们不得不重新考虑我们的选择。这就是生成器的用武之地。我们稍后将详细解释生成器在这里工作的原因,但是在此之前,我们可以放心,生成器功能将使我们能够首先读取数据,尽管不是一次全部读取。除了生成器函数,我们还可以使用生成器表达式创建生成器。
生成器表达式
早期,我们将生成器函数与常规函数进行了比较,因为它们具有许多相似的方面。对于世代表达式,我们将使用
清单理解。
lc_example是我们的列表理解力,而genex_example我们的生成器表达式则执行几乎相同的任务。请注意,两者之间的唯一区别是生成器表达式由括号而不是括号包围。如果我们将这些迭代器中的任何一个for循环放置,它们将产生相同的结果,并且将无法区分。但是,如果我们尝试在解释器中检查这些变量,它们将产生不同的结果。
此结果类似于我们尝试查看常规函数和生成器函数时所看到的结果。Python还认识到genex_example 是生成器表达式形式的生成器()。如lc_example清单所示,我们可以执行它们支持的所有操作:索引,切片,突变等。我们无法使用生成器表达式来执行此操作。生成器专门用于轻松地一次生成输出,因此不支持这些操作。但是,就像列表推导一样,我们可以在生成器表达式中实现逻辑,以在需要时形成过滤器。
实际上,我们将如何使用生成器函数或生成器表达式没有区别。一旦有了生成器表达式,就可以调用next()在它上面开始获取它将产生的值。一旦遍历了生成器表达式可以产生的所有值,就不能再使用它了。这与列表理解形成对比,列表理解可以重复使用任意数量的内容。
我们只能使用generator生成器的想法
曾经与他们的消费观念联系在一起。回想一下,当我们迭代某个迭代器时,我们会对其中的每个值执行一些操作。然后,我们使用这些处理后的值继续进行分析,这意味着通常我们可能不需要原始的迭代器。生成器完全适合这种需求,使我们能够形成一个可以使用一次的迭代器,而不必担心它在使用后会占用空间(for例如,循环)。我们讨论了next()从生成器获取值的方法,但是在for循环中使用生成器通常更好。使用next()强制我们不得不面对StopIteration自己,但是for循环使用它来知道何时停止!
生成器表达式与函数相比的一个区别是它们的简洁性。生成器函数占用多行,而我们可以将生成器表达式放在一行中。多行本身并不是一件坏事,但是它使功能更加复杂,从而可能在以后引入错误。我们将生成器函数重写为单行表达式,以读取啤酒数据。这种简洁性将在大数据分析Python生成器使用教程的稍后部分派上用场。
关键要点:generator生成器
1)生成器一次生成一个值,而不是一次提供所有值。
2)创建生成器有两种方法:生成器函数和生成器表达式。
3)generator生成器功能yield,常规功能return。
4)生成器表达式需要(),列表理解使用[]。
5)您只能使用generator生成器一次。
6)有两种从生成器获取值的方法:next()函数和for循环。所述for环通常是优选的方法。
7)我们可以使用生成器来读取文件,并一次给我们一行。
生成器:动机和用途
之前,我们讨论过对自己施加限制,迫使我们使用生成器来读取我们的数据,而不是将其读取到列表中。我们列举了大数据的问题以及我们无法将其全部存储在一个变量中。虽然称它为大数据问题仍然正确,但您也可以称它为
内存问题。假设您有一台较旧的笔记本电脑,带有大约4GB的RAM和随机存取内存。啤酒数据集的真实大小只有3MB,但假设我们要求全球每个人都给我们提供他们的食谱,因此数据集大约为3GB。如果我们将整个数据集读入一个变量,则将占用超过3GB的RAM!这将使我们几乎没有其他操作余地,更不用说其他类似大小的变量了。将我们的数据存储在列表中会占用大量内存,以至于我们进行的任何分析都将花费很长时间。
懒惰和generator生成器
现在我们知道生成器从定义的序列中产生单个值,但是仅当我们询问next()或for循环内时。我们称这种懒惰的评价。生成器之所以懒惰,是因为它们仅在我们要求时才给我们带来价值。不利的一面是,只有那个值会占用内存。最终结果是生成器的存储效率非常高,这使其成为读取和使用大数据文件的理想选择。一旦要求生成器的下一个值,旧值将被丢弃。一旦我们遍历整个生成器,它也将从内存中丢弃。
generator生成器给generator生成器供电
我们目前还没有从啤酒数据中学到任何东西。到目前为止,我们所要做的就是获取原始CSV文件并创建一个生成器,该生成器将生成CSV中的每一行,一次生成一个字符串形式。除非我们想做一些疯狂的字符串操作,否则我们需要考虑一种将数据转换为可读,可用形式的方法。下面是我们代码当前功能的表示:从文件中轻松读取文件,并从文件中输出一行内容。
generator生成器在这里再次救援!到目前为止,在大数据分析Python生成器使用教程中,我们一直在将其他结构(特别是迭代器)传递给生成器,以指示要从中生成什么序列。但是,生成器本身也是迭代器-为什么我们不创建另一个生成器来获取另一个生成器呢?我们的lines生成器完整地输出了该行,因此我们将创建第二个生成器来为我们做一些格式化。
我们的生成器的最终结果是一个列表流,每个列表都包含CSV行中的数据。如果我们遍历
lists,我们将能够轻松访问其中的数据元素并执行所需的分析!我们已经有效地为我们的数据集建立了一条管道,从原始数据集开始,并通过2个生成器将其发送,以使其成为熟悉的形式。请记住,生成器本身并不是列表,它们仅生成序列中的单个元素,并且仅占用该元素所需的数量。通过将生成器连接在一起,我们创建了一种快速,易于阅读的方式,使我们可以读取通常无法访问的数据。这种方法具有真正的力量,其重要性不可低估。在处理中间值时,我们不需要创建任何临时列表来保存中间值。在管道中增加了生成器之后,我们的代码可能如下所示:在此管道中,每个生成器负责单个操作,该操作最终将应用于数据集的所有行。尽管每个列表都有好处,但是在进行任何有意义的分析之前,仍然需要解决一些小问题。首先,我们希望采用列名,因为它们不是数据,然后将其转换为字典,这将使任何其他代码都更易于阅读。注意:如果要在自己的计算机上运行此代码,则必须记住,只能使用一次生成器。如果您在for循环中使用生成器来查看输出,则需要再次运行数据和整个管道。幸运的是,generator生成器在这里运行很快。
beerdicts 进行一些简单的格式化,这使我们的管道拥有更多的功能!
这是开始查询我们有关未来啤酒酿造选择的数据的好地方。现在我们已经有了生成器管道,我们可以开始使用生成器产生的数据并创建一些见解。我们通常使用for循环来消耗生成器,因此我们将使用一个循环来找出最流行的自酿啤酒类型。
此操作在数据整理和处理中无处不在,您可能之前已经看过。这里唯一的新事物是,我们依赖于生成器生成的字典,而不是引用包含数据的列表的列表。使用生成器,我们可以像常规大小的查询一样从任何大数据集中进行相同的查询。现在我们知道,美国IPA是数据集中最受欢迎的自酿啤酒,并且我们知道它们在数据中有多少个条目。我们可以尝试弄清楚我们的啤酒应该有多强。此数据包含在“ ABV”(
酒精体积)键。由于我们正在使用字典作为生成器流的输出,因此为什么不添加另一个生成器来细化我们要输出的确切值。
最后一个生成器构成了我们管道的最后一个,如下图所示:
我们应该特别注意sum()在abvgenerator生成器上使用的情况。sum()将接收到的所有ABV值相加并不是立即直观的。你可能认为的sum()作为减少generator生成器的输出整成一个值。通过将该总和除以美国IPA整体的数量,得出平均值。我们的数据表明,按体积计算,您的平均美国IPA约为6.4%的酒精含量!我们的最后一个生成器abv采用由beerdicts输出的字典并输出ABV键,但仅如果啤酒是美国IPA。生成器表达式上的过滤器在我们的管道中形成了强大的工具。如果我们将每个后续生成器都视为模块化组件,则可以将生成器换成其他具有更理想功能的生成器。如果我们想改变我们想要研究的啤酒种类或研究另一种啤酒特性,我们唯一需要改变的就是generator生成器操作。下图显示了生成器管道方法的不同部分。它由您要处理的一些原始数据,进行实际处理的管道以及该管道输出的最终消耗组成。按照此模式,您可以重新执行我们对啤酒数据所做的操作。如果您习惯于使用列表列表并利用所有列表方法进行分析的工作流程,那么这种新的数据整理方法可能会很奇怪。但是,数据管道是一个强大的概念,可以立即将其合并到您的代码中,您应该尝试一下。
无限的一代
可以说,自您第一次对啤酒数据集进行分析以来已经过去了几年。您利用分析中的洞察力创建了成功的美国IPA,您只需要感谢generator生成器。您每天生产数千瓶啤酒,并且需要一种分析每批次质量的方法。您回到旧笔记本电脑启动Python解释器。您开始编写一个函数来计算和检查啤酒批次的各种质量,然后停止。您不知道要提前制作多少啤酒。按天分析批次可以为我们提供离散点,但是如果我们想要连续数据怎么办?常规功能在这里不起作用!他们需要一些参数,并且将始终返回离散对象。您无法想象给常规函数提供数据流并返回连续的值流。但是您可以使用generator生成器!生成器非常适合此类任务。我们已经讨论了生成器如何一次一次产生值直到被告知停止。如果我们从不给generator生成器停止信号,它将很高兴无限地产生这些值。请看下面的例子。
whileloop始终为真,因此生成器函数将始终产生啤酒。我们没有做错任何事情,这是完全有效的代码(尽管您实际上不想实现)。这种“无限”的啤酒流如何适应我们的时间表?在最初查看啤酒数据集的过程中,CSV最初是固定数量的行。如果您可以使酿造过程自动化以将该数据输出到类似的CSV并不断更新,那么运行分析所需要做的就是再次通过生成器运行数据!可以想象,您可以在管道中创建一个生成器,以捕获不符合您期望的任何批次并实时标记它们!不幸的是,我们没有说数据,但是这个思想实验应该为Python生成器提供另一个引人注目的用例。有了generator生成器.
关键要点:generator生成器背后的动机和用途
1)生成器具有存储效率,因为它们只需要为其生成的一个值存储即可。
2)生成器很懒:它们仅在明确要求时才产生值。
3)您可以将一个生成器的输出馈送到另一个生成器的输入,以形成数据管道。
4)数据管道可以模块化并根据您的需求进行定制。
5)生成器可用于无限生成值。
结论
生成器不必是复杂的主题,只要有时间可以理解,它们就可以在任何Python程序员的作品集中占有一席之地。即使在大数据情况下,更简单的方法也无法满足需求,基于生成器的分析仍然非常重要。我们在这里没有讨论很多有关生成器的信息,但是它仍然应该为您在自己的分析生活中开始使用它们提供良好的基础。