【问题标题】:Pandas GroupBy memory deallocationPandas GroupBy 内存释放
【发布时间】:2016-06-17 09:55:46
【问题描述】:

问题

我注意到在遍历 Pandas GroupBy 对象时分配的内存在迭代后不会被释放。我使用resource.getrusage(resource.RUSAGE_SELF).ru_maxrss (second answer in this post for details) 来测量 Python 进程使用的活动内存总量。

import resource
import gc

import pandas as pd
import numpy as np

i = np.random.choice(list(range(100)), 4000)
cols = list(range(int(2e4)))

df = pd.DataFrame(1, index=i, columns=cols)

gb = df.groupby(level=0)
# gb = list(gb)
for i in range(3):
    print(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1e6)
    for idx, x in enumerate(gb):
        if idx == 0:
            print(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / 1e6)
    # del idx, x
    # gc.collect()

打印以下总活动内存(以 gb 为单位)

0.671732
1.297424
1.297952
1.923288
1.923288
2.548624

解决方案

取消注释 del idx, xgc.collect() 可以解决问题。但是,我确实必须 del 所有引用通过迭代 groupby 返回的 DataFrames 的变量(这可能会很痛苦,具体取决于内部 for 循环中的代码)。新的打印内存使用量变为:

0.671768
1.297412
1.297992
1.297992
1.297992
1.297992

或者,我可以取消注释 gb = list(gb)。生成的内存使用情况与之前的解决方案大致相同:

1.32874
1.32874
1.32874
1.32874
1.32874
1.32874

问题

  1. 为什么迭代完成后,通过 groupby 迭代产生的 DataFrames 内存没有被释放?
  2. 有没有比上述两个更好的解决方案?如果不是,这两种解决方案中哪一种“更好”?

【问题讨论】:

  • 你用的是python2还是3?
  • 这很奇怪,每次迭代都会创建新对象,并且以某种方式保留了一个引用,因此仅调用 gc.collect 是不够的。使用列表方法可以重复使用相同的对象,因此您不会看到内存增加。

标签: python python-3.x pandas memory-management


【解决方案1】:

记忆怪异

非常有趣!您不需要del idx, x。只有使用gc.collect() 才能让我保持记忆不变。这比在循环中包含 del 语句要干净得多。

【讨论】:

  • 我没有得到相同的结果。如果我不del 引用x,那么内存会增加两倍(~0.67gb -> ~1.3gb -> 2gb)。
  • 嗯...我在 iPython 中运行了这个,并且不需要 del...你在运行什么?
  • 你的意思是什么版本的熊猫? 0.18.0
  • 什么环境?在 iPython 内部?命令行?另一个完整应用程序的一部分?
【解决方案2】:

为什么迭代完成后通过groupby迭代产生的DataFrames内存没有被释放?

在你的代码中没有del 对象gb,这意味着最后它仍然存在。一件事是让迭代器到达其周期的末尾,然后我希望它会自动死亡,但是产生迭代器的对象仍然存在,以防您需要做其他事情(再次迭代、聚合等) .

【讨论】:

  • o.o wutizusaying
猜你喜欢
  • 2018-08-14
  • 2011-05-10
  • 1970-01-01
  • 1970-01-01
  • 2016-10-01
  • 2013-12-23
  • 2013-12-05
  • 2015-04-22
  • 2011-01-17
相关资源
最近更新 更多