Pandas数据帧-选择行并清除内存?

2024-06-16 09:50:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个大熊猫数据框(大小=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.ix[rows, cols]

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

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

我读过很多关于堆栈溢出的文章,但在这个主题上找不到太多。可能是我没有使用正确的关键字,所以如果你有建议,那也会有帮助。谢谢!


Tags: 数据函数内存thattablefunctionneedwhat
2条回答

你最好这样做:

指定usecols以子选择首先要read_csv的列,请参见here

然后分块读取文件,请参见here,如果要选择的行是select,则将它们分流到off,最后将结果连接起来。

伪代码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之后,用法将下降到所选行用法

我也遇到过类似的问题,我在加载之前用过滤数据解决了它。当您使用read.table读取文件时,您将整个文件加载到一个数据帧中,也可能将整个文件加载到内存中,或者由于使用不同的类型而进行一些复制,因此这是使用的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结构。

您还可以使生成器从压缩文件中读取,而Python3.3GZIP库只解压缩所需的chunck。

相关问题 更多 >