【问题标题】:pandas data frame - select rows and clear memory?熊猫数据框 - 选择行并清除内存?
【发布时间】:2013-11-09 13:14:49
【问题描述】:

我有一个大熊猫数据框(大小 = 3 GB):

x = read.table('big_table.txt', sep='\t', header=0, index_col=0)

因为我在内存限制下工作,所以我对数据框进行了子集化:

rows = calculate_rows() # a function that calculates what rows I need
cols = calculate_cols() # a function that calculates what cols I need
x = x.iloc[rows, cols]

计算行和列的函数并不重要,但它们肯定是原始行和列的较小子集。但是,当我执行此操作时,内存使用量会增加很多!最初的目标是将内存占用减少到 3GB 以下,但内存使用量却远远超过 6GB。

我猜这是因为 Python 在内存中创建了数据帧的本地副本,但没有清理它。可能还有其他事情正在发生......所以我的问题是我如何对大型数据框进行子集化并清理空间?我找不到选择行/列的函数。

我已经阅读了很多 Stack Overflow,但在这个主题上找不到太多。可能是我没有使用正确的关键字,所以如果您有建议,那也可能会有所帮助。谢谢!

【问题讨论】:

  • 我认为查看内存使用量何时上升很重要。您能否尝试评论最后一行并检查内存使用量是否超过 6GB?
  • 您可以使用模块gc 和import gc 手动清除未引用的内存,然后调用delete df 和gc.collect()。但是,在您的情况下,您应该考虑将h5py 用于大于内存的数据。

标签: python memory memory-management memory-leaks pandas


【解决方案1】:

你最好做这样的事情:

指定usecols 以在read_csv 中首先选择您想要的列,请参阅here。

然后分块读取文件,见here,如果你想要的行被选中,将它们分流,最后连接结果。

伪代码:

reader = pd.read_csv('big_table.txt', sep='\t', header=0, 
                     index_col=0, usecols=the_columns_i_want_to_use, 
                     chunksize=10000)

df = pd.concat([ chunk.iloc[rows_that_I_want_] for chunk in reader ])

这将具有恒定的内存使用量(块的大小)

加上所选行的使用 x 2,这将在您连接行时发生 在 concat 之后,使用情况将下降到选定的行使用情况

【讨论】:

    【解决方案2】:

    我遇到了类似的问题,我在加载之前通过过滤数据解决了这个问题。当您使用 read.table 读取文件时,您会将整个文件加载到 DataFrame 中,并且可能还会将整个文件加载到内存中,或者由于使用了不同的类型而出现了一些重复,所以这是使用的 6GB。

    你可以制作一个生成器来逐行加载文件的内容,我假设它是基于行的数据,一个记录是big_table.txt中的一行一行,所以

    def big_table_generator(filename):
        with open(filename, 'rt') as f:
            for line in f:
                if is_needed_row(line):   #Check if you want this row
                    #cut_columns() return a list with only the selected columns
                    record = cut_columns(line)    
                    yield column
    
    
    gen = big_table_generator('big_table.txt')
    df = pandas.DataFrame.from_records(list(gen))
    

    请注意 list(gen),pandas 0.12 和以前的版本不允许生成器,因此您必须将其转换为列表,以便生成器提供的所有数据都放在内存中。 0.13 将在内部做同样的事情。此外,您需要两倍的数据内存,一个用于加载数据,另一个用于将其放入 pandas NDframe 结构。

    您也可以使生成器从压缩文件中读取,使用 python 3.3 gzip 库仅解压缩所需的块。

    【讨论】:

      猜你喜欢
      • 2018-09-20
      • 2019-06-29
      • 1970-01-01
      • 2016-12-08
      • 2018-05-20
      • 2021-07-17
      • 1970-01-01
      • 2015-12-03
      • 2017-06-14
      相关资源
      最近更新 更多