【问题标题】:Trying to optimize a Python for loop for large data set (4 million rows)尝试为大型数据集(400 万行)优化 Python for 循环
【发布时间】:2021-05-25 23:15:41
【问题描述】:

我是 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 - 这是“最终”数据框,其中包含来自 Combinations 的 4 个唯一项目以及来自 CalculatedTotalPoints 函数的附加 PropList。
  • CalculateTotalPoints - 此函数接受 4 个项目 (i) 的列表以及对具有所有属性值 (ItemDict) 的数据框的引用。它实际上只是在执行一些简单的加法和除法运算,并添加一些逻辑并返回各种累积属性的列表。

我确信这里发生了很多“不是很棒的 Python”的事情,但我目前的想法是:

  • Python 可能有更好/更快的方法来实现这个循环,而不是指定一个 for 循环(列表理解?)
  • ItemDict 不是特别大,但可能每次都传递给函数是不必要的开销
  • 由于 CombinationSet 数据帧的每一行都是相互独立的,我应该尝试实现多处理,以便可以处理多行

编辑 1: 我无法弄清楚如何隔离代码足以产生一个小示例问题。不适合后期长寿,但我已将主要代码添加到 for 循环、支持函数和示例数据到 Github Gist(已删除)

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

CombinationSets.loc[Combinations.index(i), 'Density':] = PropList

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

【问题讨论】:

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

标签: python python-multiprocessing


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2013-08-28
    • 2019-02-16
    • 1970-01-01
    • 2015-04-15
    • 2020-10-09
    • 1970-01-01
    • 1970-01-01
    • 2020-11-07
    • 1970-01-01
    相关资源
    最近更新 更多