我在理解为什么Pandas Dataframes没有从内存中正确清除时遇到问题。我的机器达到16Gb的内存之后,我发现它应该保持在400 Mb左右。我创建一个DataFrame,然后在同一个函数内创建一个副本。多次评估此功能。每次评估函数时,内存都会增加 - 在下面的示例中为337 Mb:
import pandas as pd
import numpy as np
from memory_profiler import profile
@profile
def loop_df():
for _ in xrange(100):
copy_df()
# Create a df and then copy it
def copy_df():
X = pd.DataFrame(np.random.rand(100000,10))
X2 = X.loc[0:1000,:]
return
loop_df()
# Returns the following memory usage:
#Line # Mem usage Increment Line Contents
#================================================
# 13 100.3 MiB 0.0 MiB @profile
# 14 def loop_df():
# 15 437.8 MiB 337.5 MiB for _ in xrange(100):
# 16 437.8 MiB 0.0 MiB copy_df()
有各种各样的线索涉及到这一点,但没有一个像样的解决方案:Memory leak using pandas dataframe,https://github.com/pandas-dev/pandas/issues/6046,https://github.com/pandas-dev/pandas/issues/2659,Pandas: where's the memory leak here?
对于可以采取哪些措施来避免这种情况的任何建议都是受欢迎的。到目前为止,使用垃圾收集器使用简单的示例,但在我的复杂代码中失败。使用多处理池也可以使用我复杂的代码。然而,拥有一个不必使用多处理模型的解决方案会很好。
任何人都可以解释为什么当Numpy数组和列表等Python对象不会导致这种行为时会发生这种情况?这是一个错误或DataFrame对象的预期行为?
答案 0 :(得分:3)
使用del
后跟gc.collect()
似乎可以解决问题:
import pandas as pd
import numpy as np
import gc
from memory_profiler import profile
@profile
def loop_df():
for _ in xrange(100):
copy_df()
# Create a df and then copy it
@profile
def copy_df():
X = pd.DataFrame(np.random.rand(100000,10))
X2 = X.loc[0:1000,:]
del X, X2
gc.collect()
loop_df()
然后,如果你的内存不足,这里有一个使用numpy memmap(内存映射)数据结构的可能解决方案:
import pandas as pd
import numpy as np
from memory_profiler import profile
import gc
@profile
def loop_df():
for _ in xrange(100):
copy_df()
@profile
def copy_df():
mmap = np.memmap('mymemmap', dtype='float64', mode='w+', shape=(100000,10))
mmap[:] = np.random.rand(100000,10)
df = pd.DataFrame(mmap)
df2 = df.loc[0:1000,:]
del df, df2, mmap
gc.collect()
pass
if __name__ == '__main__':
loop_df()
内存映射文件用于访问磁盘上的大段文件,而无需将整个文件读入内存。
抱歉,我无法解释为什么您的示例代码不会释放pandas数据。我怀疑它与使用原生数组或其他东西的numpy和pandas有关。