将pandas导入为pd import gc
我在使用for循环中的Pandas DataFrames管理内存时遇到了困难。我正在合并大约10-20 GB的文件然后我正在进行groupby聚合(我的总RAM是128 GB,所以我应该大部分都没问题)。
我的工作流程就这样建立起来了。做一些非常内存密集的任务,命中或不命中内存限制(128 GB),如果命中限制然后将数据拆分成块(在ith chunk上执行任务,写入磁盘,在第i + 1块上执行任务,附加到磁盘)。有关说明,请参阅下面的伪代码:
def somethingfunc(x):
#read a whole bunch of data w/ pandas, merge and do groupbys
for i in range(x):
#read data
data1 = pd.read_csv(...)
data2 = pd.read_csv(...)
#get ith chunk of data1
data1 = function_that_gets_ith_chunk_of_data1(data1)
#merge data
datamerge = pd.merge(..., how = 'inner')
datamerge = datamerge.groupby(...)
#either write chunk to memory or append
if i == 0:
datamerge.to_csv(...)
elif i>0:
datamerge.to_csv(..., mode= 'a', header ='none')
for x in range(10):
try:
somethingfunc(x+1)
#do something memory intensive dividing data into (x+1) chunks
except MemoryError:
pass
else:
break
当我从一个块中的数据执行任务到2个块时,问题出现了。当我在1块中执行任务并且达到内存限制时,我希望它在进入2之前从1块进程中释放所有数据。我尝试了多种方法(确保进程是自己的函数,显式调用gc.collect()等)。我知道我的代码有效,因为我不会总是达到内存限制,但是当我这样做时,我的大块解决方案无效。有没有人知道释放上一次迭代使用的所有数据的好方法?
如果在函数内部创建了一组变量,并且如果所述函数终止,那么python不仅会保存这些变量,而且gc.collect()无法清除它们,这似乎很奇怪。
编辑:我把注意力转移到Dask,我目前正在阅读文档,但与此同时,如果有人知道如何在Dask中做到这一点,这也是一个可以接受的答案
答案 0 :(得分:0)
这并不完全回答我上面的问题,但似乎正确的方法是在dask中。这将隐含地进行上面讨论的块迭代。