使用Pandas分块读取超大CSV文件时遇内存错误的求助
解决思路
你的报错根源在于Python解析引擎内部处理行逻辑时的内存溢出,同时持续通过concat累积结果也会导致内存占用不断攀升,以下是针对性的解决方法:
1. 切换到C解析引擎(优先解决报错)
你当前使用的engine='python'存在低效的行处理逻辑,即使未设置skiprows参数,也会触发内存密集型的集合运算。切换到默认的C引擎(速度更快、内存占用更低):
import pandas as pd chunk_size = 1000000 my_df = pd.DataFrame() i = 1 def convert_data(value): try: return float(value) except: return 0.778 # 移除engine='python',使用默认C引擎 for chunk in pd.read_csv(path, delimiter='~', dtype={'FIELD': 'object', 'ID_TAXPAYER': 'object', 'PYEAR': 'object'}, usecols=['PYEAR', 'DATA', 'FIELD', 'ID_TAXPAYER'], chunksize=chunk_size, converters={'DATA': convert_data}): chunk = chunk[chunk['FIELD'].str.contains("field", na=False)] chunk['FIELD'] = chunk['FIELD'].str.replace('field_', '', regex=False).str.replace('_', '.', regex=False) filtered_df = chunk[chunk['FIELD'] == '910.00.001'] print(i) i+=1 my_df = pd.concat([my_df, filtered_df], ignore_index=True) print(my_df)
2. 避免内存累积:用临时文件存储中间结果
持续concat会让my_df占用内存越来越大,改为每次处理完chunk就写入临时CSV,最后再合并结果:
import pandas as pd import gc chunk_size = 500000 # 适当减小chunk尺寸 temp_file = 'filtered_temp.csv' first_write = True def convert_data(value): try: return float(value) except: return 0.778 for chunk in pd.read_csv(path, delimiter='~', dtype={'FIELD': 'object', 'ID_TAXPAYER': 'category', 'PYEAR': 'int32'}, usecols=['PYEAR', 'DATA', 'FIELD', 'ID_TAXPAYER'], chunksize=chunk_size): # 提前过滤,减少后续处理数据量 chunk = chunk[chunk['FIELD'].str.startswith('field_', na=False)] chunk['FIELD'] = chunk['FIELD'].str.replace('field_', '', regex=False).str.replace('_', '.', regex=False) filtered_df = chunk[chunk['FIELD'] == '910.00.001'] filtered_df['DATA'] = filtered_df['DATA'].apply(convert_data) # 写入临时文件 filtered_df.to_csv(temp_file, mode='a', header=first_write, index=False) first_write = False # 手动释放内存 del chunk, filtered_df gc.collect() # 最终读取结果 my_df = pd.read_csv(temp_file) print(my_df)
3. 优化数据类型,降低内存占用
针对不同列设置最优数据类型,大幅减少单chunk内存占用:
PYEAR如果是4位年份,设为int32即可ID_TAXPAYER如果是重复率高的字符串,设为category类型
dtype={'FIELD': 'object', 'ID_TAXPAYER': 'category', 'PYEAR': 'int32'}
4. 调整chunk_size至合适范围
100万行的chunk对16GB内存来说偏大,尝试将chunk_size调整为30万-50万行,降低单次读取的内存压力。
5. 显式触发垃圾回收
在循环中加入gc.collect(),手动释放不再使用的变量内存,避免Python垃圾回收延迟导致的内存堆积。
内容的提问来源于stack exchange,提问作者Yerassyl Pirzhanov
相关产品推荐
相关产品推荐

