我注意到迭代后迭代通过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, x
和gc.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
答案 0 :(得分:1)
非常有趣!您不需要del idx, x
。只有使用gc.collect()
才能保持记忆不变。在循环中使用del
语句会更清晰。
答案 1 :(得分:0)
为什么迭代完成后迭代通过groupby得到的DataFrames的内存不会被释放?
您的代码中没有任何地方del
对象gb
,这意味着最终它仍然存在。有一件事是让迭代器到达它的循环结束,然后我会期望它自动死亡,但产生迭代器的对象仍然存在,以防你需要做其他事情(再次迭代,聚合等)