尝试为大型数据集(400万行)优化Python for循环

尝试为大型数据集(400万行)优化Python for循环,python,python-multiprocessing,Python,Python Multiprocessing,我是Python新手,已经习惯了这些非常方便的隐式数组/列表操作,所以请耐心听我说。我已经完成了一个概念验证代码(120个组合),但正如预期的那样,在处理完整数据集(400万个组合)时,它正在经历一个显著的减速。当前的减速在以下for循环中: for i in Combinations: PropList = function.CalculateTotalPoints(ItemDict, i) CombinationSets.loc[Combinations.index(i), 'Densi

我是Python新手,已经习惯了这些非常方便的隐式数组/列表操作,所以请耐心听我说。我已经完成了一个概念验证代码(120个组合),但正如预期的那样,在处理完整数据集(400万个组合)时,它正在经历一个显著的减速。当前的减速在以下for循环中:

for i in Combinations:

PropList = function.CalculateTotalPoints(ItemDict, i)

CombinationSets.loc[Combinations.index(i), 'Density':] = PropList
我试着不让它成为一堵文字墙,而是提供足够的信息来理解目标

  • 组合-这是一个数据框,包含4项(400万行)的所有唯一组合。我最终在循环结束后删除了它,而不再需要它
  • PropList-这是返回的特定行中4项的累积属性列表
  • ItemDict-这是一个数据帧,包含各个项目的所有属性值
  • CombinationSets-这是“最终”数据框,其中包含来自组合的4个唯一项以及CalculatedTotalPoints函数中附加的PropList
  • CalculateTotalPoints-此函数接受4个项目(i)的列表和对具有所有属性值(ItemDict)的数据帧的引用。它实际上只是做了一系列简单的加法和除法运算,加入了一些逻辑,并返回了各种累积属性的列表
我确信这里发生了很多“不太棒的Python”的事情,但我目前的想法是:

  • Python可能有更好/更快的方法来实现这个循环,而不是指定for循环(列表理解?)
  • ItemDict并不是非常大,但是每次传递给函数可能是不必要的开销
  • 因为CombinationSet数据帧的每一行都是相互独立的,所以我应该尝试实现多处理,以便可以处理多行
编辑1: 我不知道如何将代码隔离到足以产生一个小问题的程度。不适合于后期使用,但我已将主代码添加到for循环、支持函数,并将示例数据添加到Github Gist(已删除)

编辑2: 从我在其他地方读到的内容来看,在Python中,for循环通常不是首选的循环方法。我还没有成功地将我的函数矢量化。但是,我确实研究了这个for循环的计时、函数(内部有一个for循环)和PropList的分配。当运行一个小的(120个组合)或一个大的(450万)集合时,for循环和函数具有相似的(相当快的)性能。在这两种情况下,下一行所用的时间最长。对于大型数据集,需要约1秒的时间

CombinationSets.loc[Combinations.index(i), 'Density':] = PropList
编辑3:
通过不执行合并操作
CombinationSets.loc,我能够减少循环操作的时间[…
在循环中,我列出了返回的
PropList
。退出for循环后,我立即执行了合并操作。由于目前设置的是,for循环的单次运行时间为~0.004s,而不是1秒。可能还可以进行其他优化,但我会将其保存到单独的帖子中。

移动for循环外部的列表到数据帧合并操作。请参见编辑3。

您需要显示一些要使用的数据。请提供预期的(MRE)。我们应该能够复制和粘贴连续的代码块,执行该文件,并复制您的问题以及跟踪问题点的输出。这使我们能够根据您的测试数据和所需的输出测试我们的建议。您发布的代码缺少必要的符号定义。看起来您正在使用PANDAS,其中c如果您要丢弃整个数据帧上可用的矢量化操作。请将其作为MRE的一部分。我希望有一个更一般的答案,并避免只发布一堆代码来涉猎,但似乎答案可能更细微,需要更多细节。因为我在动态学习Python,代码并不容易“chunckable”,所以我想看看如何最好地做到这一点。谢谢。