使用Pandas写入CSV时的内存占用优化问题
Pandas写入CSV时的内存占用优化问题
嘿,我来帮你搞定这个内存难题~你当前代码的核心痛点其实是整个DataFrame已经完整加载到内存里了,哪怕你分块写入,源头的大数据集还是占着t3.small有限的内存(一般只有2G),这才是内存吃紧的根源。给你几个针对性的优化方案,按优先级排序:
1. 最关键:分块读取原数据,边读边写
不要一次性把整个CSV加载成DataFrame,而是用Pandas的read_csv自带的chunksize参数分块读取,读一块就写一块,这样内存里永远只保留一小部分数据,直接从根源上降低内存占用。
示例代码:
import pandas as pd import gc # 可根据内存情况调整chunksize,比如10000行 chunk_size = 10000 output_path = "your_output.csv" # 打开输出文件 with open(output_path, 'w', newline='') as f: # 遍历每个读取到的chunk for idx, chunk in enumerate(pd.read_csv("your_input.csv", chunksize=chunk_size)): # 这里可以对chunk做你需要的预处理(如果有的话) # ... # 写入chunk:仅第一块写入表头 chunk.to_csv(f, header=(idx == 0), index=False, date_format='%Y-%m-%d %H:%M:%S') # 小内存机器可手动释放内存 del chunk gc.collect()
2. 提前指定数据类型,减少内存开销
Pandas默认会自动推断数据类型,经常会把小范围整数设成int64、重复率高的字符串设成object,这些都会浪费大量内存。提前指定更合适的数据类型能大幅降低每个chunk的内存占用。
比如:
# 定义各列的目标数据类型 dtype_spec = { "category_column": "category", # 重复率高的字符串列用category类型 "small_int_column": "int8", # 小范围整数用int8/int16 "float_column": "float32" # 不需要高精度的浮点数用float32 } # 读取时指定dtype for idx, chunk in enumerate(pd.read_csv("your_input.csv", chunksize=chunk_size, dtype=dtype_spec)): # 后续写入逻辑不变 chunk.to_csv(f, header=(idx == 0), index=False, date_format='%Y-%m-%d %H:%M:%S')
如果有日期列,也可以提前指定parse_dates参数,避免Pandas后续重复解析:
from datetime import datetime def date_parser(date_str): return datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S") pd.read_csv("your_input.csv", chunksize=chunk_size, parse_dates=["date_column"], date_parser=date_parser)
3. 极端情况:用原生csv模块替代Pandas写入
如果Pandas的to_csv还是有额外内存开销,你可以把chunk转成原生Python列表,用内置的csv模块写入,更轻量:
import csv with open(output_path, 'w', newline='') as f: writer = csv.writer(f) for idx, chunk in enumerate(pd.read_csv("your_input.csv", chunksize=chunk_size)): if idx == 0: # 写入表头 writer.writerow(chunk.columns.tolist()) # 把chunk转成列表写入 writer.writerows(chunk.values.tolist()) del chunk gc.collect()
4. 其他小细节优化
- 彻底清理原DataFrame:如果你之前是先把整个文件读成DataFrame再分块写,一定要先删掉原DataFrame再开始写入:
del dataframe; gc.collect() - 调整
chunksize:不是越大越好,太小会增加IO次数,太大还是会占内存,建议在5000-20000行之间测试找平衡点 - 关闭不必要特性:读取时设置
index_col=False,避免Pandas自动生成索引占用内存
备注:内容来源于stack exchange,提问作者Ajimi Mol
相关产品推荐
相关产品推荐

