Pandas Group通过内存释放

时间:2016-03-03 21:00:28

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

问题

我注意到迭代后迭代通过Pandas GroupBy对象时分配的内存不会被释放。我使用resource.getrusage(resource.RUSAGE_SELF).ru_maxrsssecond 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. 有没有比上述两个更好的解决方案?如果没有,这两个解决方案中的哪一个更好"?

2 个答案:

答案 0 :(得分:1)

记忆奇怪

非常有趣!您不需要del idx, x。只有使用gc.collect()才能保持记忆不变。在循环中使用del语句会更清晰。

答案 1 :(得分:0)

  

为什么迭代完成后迭代通过groupby得到的DataFrames的内存不会被释放?

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