pandas dataframe - 选择行和清除内存?

时间:2013-10-30 04:59:12

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

我有一个大型的pandas数据帧(大小= 3 GB):

  

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

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

  

rows = calculate_rows()#一个计算我需要的行的函数

     

cols = calculate_cols()#计算我需要的cols的函数

     

x = x.ix [rows,cols]

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

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

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

2 个答案:

答案 0 :(得分:7)

你做这样的事情要好得多:

指定usecols以从read_csv子选择您想要的列,请参阅here

然后以块的形式读取文件,请参阅here,如果您想要的行被选中,将它们分流到关闭状态,最后连接结果。

伪代码ish:

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.ix[rows_that_I_want_] for chunk in reader ])

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

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

答案 1 :(得分:4)

我遇到了类似的问题,我在加载前用过滤数据解决了这个问题。当您使用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))

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

你也可以让生成器从压缩文件中读取,python 3.3 gzip库只能解压缩所需的chuncks。