2017-01-23 87 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有關。