【问题标题】:Pandas Dataframe memory issuesPandas Dataframe 内存问题
【发布时间】:2017-06-08 05:07:02
【问题描述】:

我无法理解为什么 Pandas 数据帧没有从内存中正确清除。我在机器达到 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?

欢迎任何关于如何避免这种情况的建议。到目前为止,使用垃圾收集器处理了简单的示例,但在我的复杂代码中失败了。使用多处理池也适用于我的复杂代码。但是,最好有一个不需要使用多处理模型的解决方案。

谁能解释为什么当 Python 对象(如 Numpy 数组和列表)不会导致这种行为时会发生这种情况?这是一个错误还是 DataFrame 对象的预期行为?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    使用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 使用本机数组或其他东西有关。

    【讨论】:

      猜你喜欢
      • 2018-05-06
      • 2013-12-28
      • 2018-10-07
      • 1970-01-01
      • 2018-11-17
      • 1970-01-01
      • 2017-08-25
      • 2021-11-22
      • 1970-01-01
      相关资源
      最近更新 更多