熊猫似乎触发了一个内存泄漏,当它从一个数据帧复制一个值。在
在每次迭代开始时,通过从初始数据帧复制一个数据帧来创建一个数据帧。第二个变量是通过从当前数据帧复制一个值来创建的。在
迭代结束时,每个迭代都会被两个变量打印出来。used memory increases!在
我认为在某个时刻(可能在读取dataframe值时)可能会有一些隐式复制。在
快速修复此问题会导致在每次迭代时应用垃圾回收器,但这是一个相当昂贵的解决方案:该过程至少慢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())))
好吧,看起来真正的痛苦来自于
df_ind
的创建方式。在使用引用到原始数据帧},则可能会有点风险。在
df
似乎可行,但是如果我们打算修改{使用原始数据帧
df
的副本会触发内存泄漏。可能有一些来自df
的无用元素的隐式副本。这些复制的元素不被del
,捕获,而是被gc.collect()
捕获。这是一个时间成本,因为这个操作需要时间。在下面列出了解决此内存泄漏的不同尝试及其结果:
总而言之:
如果想要修改temp dataframe,那么不要使用pandas。你可以使用字典或压缩列表来得到你想要的。
如果不想修改temp dataframe,那么使用pandas和显式选项
df_ind = df.copy(deep=False)
相关问题 更多 >
编程相关推荐