a b*_*a b 6 python memory memory-leaks memory-management 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,但在这个主题上找不到多少.可能是我没有使用正确的关键字,所以如果你有建议,这也可能有所帮助.谢谢!
做这样的事情要好得多:
指定usecols要在第一个位置选择所需的列read_csv,请参见此处.
然后以块的形式读取文件,看这里,如果你想要的行被选中,将它们分流到关闭,最后连接结果.
伪码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 ])
Run Code Online (Sandbox Code Playgroud)
这将具有恒定的内存使用量(块的大小)
加上选定的行使用次数x 2,这将在concat之后连续使用将发生在选定的行使用情况下时发生
我也遇到过类似的问题,我在加载之前通过过滤数据解决了这个问题。当您使用 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))
Run Code Online (Sandbox Code Playgroud)
请注意 list(gen),pandas 0.12 和以前的版本不允许生成器,因此您必须将其转换为列表,以便生成器提供的所有数据都放在内存中。0.13 会在内部做同样的事情。此外,您还需要两倍的数据内存,一份用于加载数据,另一份用于将其放入 pandas NDframe 结构中。
您还可以使生成器从压缩文件中读取,使用 python 3.3 gzip 库仅解压缩所需的块。