【发布时间】:2020-09-03 19:14:05
【问题描述】:
我知道关于这个主题有几个问题,但我似乎无法有效地进行。我有大型输入数据集(2-3 GB) 在我的机器上运行,其中包含8GB 的内存。我正在使用安装了pandas 0.24.0 的spyder 版本。输入文件目前需要大约一个小时来生成大约10MB 的输出文件。
我试图通过使用下面的代码对输入文件进行分块来优化该过程。本质上,我将chunk 输入文件分成更小的段,通过一些代码运行它并导出更小的输出。然后我删除分块信息以释放内存。但是内存仍然在整个操作过程中建立,并最终花费了相似的时间。我不确定我做错了什么:
文件的内存使用详情为:
RangeIndex: 5471998 entries, 0 to 5471997
Data columns (total 17 columns):
col1 object
col2 object
col3 object
....
dtypes: object(17)
memory usage: 5.6 GB
我通过将cols_to_keep 传递给use_cols 来对df 进行子集化。但是每个文件的标题都不同,所以我使用位置索引来获取相关的标题。
# Because the column headers change from file to file I use location indexing to read the col headers I need
df_cols = pd.read_csv('file.csv')
# Read cols to be used
df_cols = df_cols.iloc[:,np.r_[1,3,8,12,23]]
# Export col headers
cols_to_keep = df_cols.columns
PATH = '/Volume/Folder/Event/file.csv'
chunksize = 10000
df_list = [] # list to hold the batch dataframe
for df_chunk in pd.read_csv(PATH, chunksize = chunksize, usecols = cols_to_keep):
# Measure time taken to execute each batch
print("summation download chunk time: " , time.clock()-t)
# Execute func1
df1 = func1(df_chunk)
# Execute func2
df2 = func1(df1)
# Append the chunk to list and merge all
df_list.append(df2)
# Merge all dataframes into one dataframe
df = pd.concat(df_list)
# Delete the dataframe list to release memory
del df_list
del df_chunk
我尝试过使用 dask,但使用简单的 pandas 方法会出现各种错误。
import dask.dataframe as ddf
df_cols = pd.read_csv('file.csv')
df_cols = df_cols.iloc[:,np.r_[1:3,8,12,23:25,32,42,44,46,65:67,-5:0,]]
cols_to_keep = df_cols.columns
PATH = '/Volume/Folder/Event/file.csv'
blocksize = 10000
df_list = [] # list to hold the batch dataframe
df_chunk = ddf.read_csv(PATH, blocksize = blocksize, usecols = cols_to_keep, parse_dates = ['Time']):
print("summation download chunk time: " , time.clock()-t)
# Execute func1
df1 = func1(df_chunk)
# Execute func2
df2 = func1(df1)
# Append the chunk to list and merge all
df_list.append(df2)
delayed_results = [delayed(df2) for df_chunk in df_list]
引发错误的行:
df1 = func1(df_chunk)
name_unq = df['name'].dropna().unique().tolist()
AttributeError: 'Series' object has no attribute 'tolist'
我已经通过了许多函数,但它只是继续抛出错误。
【问题讨论】:
-
你不想使用数据库? sqlite 也许?
-
Del 不会立即释放内存。如果内存未使用,它会等待垃圾收集器启动以释放内存。您可以使用 gc.collect() 强制 gc。
-
如果行顺序不重要,为什么不让每个 for 迭代在一个线程中运行?
-
我会看看
gc.collect()函数。以前没听说过。您能否再解释一下第二条评论。我怎么能在一个线程中运行它? -
内存分析器是帮助隔离意外使用源的工具。
标签: python pandas memory chunked-encoding