【发布时间】:2017-02-01 21:05:28
【问题描述】:
当反复从数据帧复制一个值时,pandas 似乎触发了内存泄漏。
在每次迭代开始时,通过从初始数据帧复制来创建数据帧。通过从当前数据框中复制单个值来创建第二个变量。
在每次迭代结束时,删除这两个变量,并打印当前进程使用的内存(每 1000 次迭代)。 used memory increases!
我认为在某些时候可能会有一些隐式副本(可能在读取数据帧值时)。
快速解决此问题会导致在每次迭代中应用垃圾收集器,但这是一个相当昂贵的解决方案:该过程至少慢 10 倍。
有没有明确解释为什么会出现这个问题?
import os, gc
import psutil, pandas as pd
N_ITER = 100000
DF_SIZE = 10000
# Define the DataFrame
df = pd.DataFrame(index=range(DF_SIZE), columns=['my_col'])
df['my_col'] = range(DF_SIZE)
def memory_usage():
"""Return the memory usage of the current python process."""
return psutil.Process(os.getpid()).memory_info().rss / 1024 ** 2
if __name__ == '__main__':
for i in range(N_ITER):
df_ind = pd.DataFrame(df.copy())
val = df_ind.at[4242, 'my_col'] # The line that provokes the leak!
del df_ind, val # Useless
# gc.collect() # Garbage Collector prevents the leak but is slow
if (i % 1000) == 0:
print('Iter {}\t {} MB'.format(i, int(memory_usage())))
【问题讨论】:
-
如果调用
gc.collect()释放内存,那么这是完全正常的预期行为。某处有一些循环引用阻止引用计数机制释放内存。让你的程序运行;如果太多未声明的、可声明的对象堆积起来,GC 会自动运行并清理它们。 -
感谢您的回答。我让代码运行,然后等着看。那么你将如何防止这些循环引用呢?
-
这必须在 Pandas 实现中完成。
标签: python pandas memory-leaks