pandas.read_csv的chunksize参数通过分块读取避免MemoryError,需结合文件字节数、字段宽度估算合理值,并在循环内完成清洗与to_sql批量插入,配合偏移量实现断点续传。

用 pandas.read_csv 的 chunksize 参数控制内存占用
直接 pd.read_csv('big.csv') 读取几个 GB 的文件,大概率触发 MemoryError。关键不是“能不能读”,而是“每次只读多少行”。chunksize 参数就是干这个的——它不返回 DataFrame,而是返回一个可迭代的 TextFileReader 对象。
常见错误是误以为设了 chunksize=10000 就万事大吉:如果每行字段多、含长文本或缺失值多,实际内存开销可能远超预期。建议先用 head -n 10000 big.csv | wc -c 估算单 chunk 字节数,再结合机器可用内存反推合理值(例如 50MB 内存余量 ≈ chunksize 2–5 万,视字段宽度而定)。
-
chunksize必须是正整数,不能是None或字符串 - 若 CSV 含 quoted commas 或换行符,务必同步传入
quoting=csv.QUOTE_MINIMAL和lineterminator='\n',否则 chunk 边界会错位 - 不要在循环里反复调用
read_csv;正确写法是for chunk in pd.read_csv(..., chunksize=N):
清洗逻辑必须在 chunk 循环内完成,不能后置
分块读取后立刻清洗,是避免二次加载的唯一办法。一旦把原始 chunk 存成临时 list 或 dict,就等于又把数据全塞进内存——和不分块没区别。
典型清洗动作包括:空值填充(chunk['col'].fillna('N/A'))、类型转换(chunk['ts'] = pd.to_datetime(chunk['ts'], errors='coerce'))、字符串 strip(chunk['name'] = chunk['name'].str.strip())。注意 errors='coerce' 能防止时间解析失败中断整个 chunk。
立即学习“Python免费学习笔记(深入)”;
从 CSV 数据集生成图数据库加载器和三元组映射。将表格 CSV 数据转换为图数据库可直接使用的节点、边和三元组。
- 避免使用
apply(lambda x: ...)处理整列,优先用向量化方法(如str.replace、astype) - 若需根据全局统计值清洗(比如用全量均值填充),得先单独扫一遍文件算出统计量,再分块清洗——不能边读边算均值(会偏)
- 清洗后立刻检查
chunk.dtypes,确认没有意外的object类型残留(尤其是数字列被当字符串读入)
用 chunk.to_sql 批量插入,但必须关掉 if_exists='append' 的默认检查
to_sql 默认每次执行都会先查一次表是否存在、再查索引,分块时这一步纯属浪费。更严重的是,如果数据库表已存在且有主键/唯一约束,不加 method='multi' 就会变成逐行 INSERT,性能暴跌。
实操中推荐组合:chunk.to_sql('table', con=engine, if_exists='append', index=False, method='multi')。其中 method='multi' 让 pandas 把 chunk 拼成一条带多个 VALUES 的 INSERT 语句,吞吐量能提升 5–10 倍。
- PostgreSQL 用户需额外安装
psycopg2,且确保engineURL 中包含?options=-c%20search_path%3Dschema_name指定 schema - MySQL 用户注意
max_allowed_packet配置,chunk 过大时可能报Packet sequence number wrong,此时要调大该参数或减小chunksize - SQL Server 用户必须指定
dtype显式映射,否则object列会被映射成nvarchar(max),导致后续查询极慢
异常中断时如何续跑?靠文件偏移量 + 记录已处理行数
几小时的导入过程卡在第 87 个 chunk,重头跑太伤。可靠做法是:不用行号(CSV 行号易受换行符干扰),改用字节偏移量记录进度。
原理是打开文件后用 f.tell() 获取当前读取位置,在每个 chunk 处理完后把该位置写入一个 progress.offset 文件。下次启动时先读该 offset,再用 f.seek(offset) 跳过已处理部分,最后用 pd.read_csv(f, ...) 继续——注意此时不能再传 chunksize,得手动按行读直到下一个完整 chunk 边界。
- 不要依赖 CSV 的“第 N 行”作为断点,Windows 换行符
\r\n和 Unix 的\n会让行计数失效 - 偏移量文件必须在每个 chunk 成功写入数据库后才更新,否则会出现“写库成功但进度未记”的丢失
- 生产环境建议用数据库表存进度(如
import_progress表),比文件更可靠

















