2017-01-23 97 views
2

我有问题,理解为什么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 dataframehttps://github.com/pandas-dev/pandas/issues/6046https://github.com/pandas-dev/pandas/issues/2659Pandas: where's the memory leak here?

任何有关可以做什么以避免这种情况的建议是值得欢迎的。到目前为止,使用垃圾回收器与简单的例子一起工作,但在我的复杂代码中失败。使用多处理池也适用于我复杂的代码。但是,最好有一个不涉及使用多处理模型的解决方案。

任何人都可以解释为什么发生这种情况时,如Numpy数组和列表的Python对象不会导致此行为?这是一个错误还是DataFrame对象的预期行为?

回答

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() 

内存映射文件被用于访问的在磁盘上的文件大小的段,而不读取整个文件到内存中。

对不起,我不能解释为什么你的示例代码不能释放熊猫数据已经。我怀疑它与使用本地数组或其他东西的numpy和pandas有关。