chunksize参数需设为正整数(如50000),返回TextFileReader迭代器;不可为0或负数,避免内存溢出或I/O过载;配合ignore_index=True合并、避免循环concat,超10GB宜换csv模块/dask/parquet。

chunksize 参数怎么用才不报错
直接传 chunksize 是最常用也最稳妥的分块方式,它让 pd.read_csv() 返回一个 TextFileReader 迭代器,而不是一次性加载全部数据。关键不是“设多大”,而是“设得合理”——太大仍会内存溢出,太小则 I/O 开销陡增。
- 典型安全起点是
chunksize=50000(5 万行),适用于普通 8–16GB 内存机器;若文件含大量字符串列,建议先试10000 - 不要写
chunksize=0或负数,会抛ValueError: chunksize must be > 0 - 如果文件有 BOM 头或编码异常,
chunksize不会帮你绕过,必须显式加encoding='utf-8-sig'或其他正确编码 - 遇到
MemoryError时,别急着换工具——先减半chunksize,再观察;90% 的情况只是块设太大了
iterator=True 和 chunksize 有什么区别
两者都返回 TextFileReader,但行为不同:chunksize 是“定额分批”,iterator=True 是“按需取块”。后者更灵活,适合你不确定每块该读多少行、或想动态调整块大小的场景。
-
iterator=True本身不指定块大小,必须配合.get_chunk(n)才能读数据;不调就不会加载任何内容 - 你可以第一次
get_chunk(1000)看前几行结构,第二次根据列类型决定用get_chunk(50000)做主处理 - 若中途想提前退出(比如只统计前 100 万行),
iterator=True更容易控制流程;而chunksize的 for 循环必须走完或手动break - 注意:
iterator=True和chunksize不能同时设,否则 pandas 会忽略iterator并警告
合并分块结果时最常踩的坑
很多人以为 pd.concat(chunks) 就完事了,结果发现内存翻倍、索引错乱、甚至列顺序不一致——问题往往出在 chunk 之间隐含的差异上。
- 每个
chunk默认带自己的行索引(从 0 开始),直接concat会导致重复索引;务必加ignore_index=True - 如果原始 CSV 某些 chunk 缺失某列(比如空行、格式错位),
concat可能报ValueError: All objects passed were None或列对不齐;建议加sort=False并检查chunk.columns.equals(chunks[0].columns) - 别在循环里反复
pd.concat([df, new_chunk])——这是 O(n²) 操作,10 个 chunk 就可能卡住;始终用列表收集,最后一次性concat - 如果最终不需要完整 DataFrame,只是求和/计数/去重等聚合,就根本别
concat;每块算完累加变量即可,省内存又快
什么时候该放弃 pandas,换别的方案
当你的 CSV 超过 10GB、列数超 200、且需要频繁随机访问或复杂连接时,chunksize 已经不是“优化”,而是“将就”。这时硬扛只会拖慢开发节奏。
- 单次分析只要几个统计值?用
csv模块 + 生成器逐行解析,内存恒定在 KB 级 - 要反复查询、过滤、关联多个大文件?考虑
dask.dataframe,接口兼容 pandas,但底层自动分块+延迟计算 - 后续还要做机器学习训练?直接导成
parquet格式(用pyarrow),之后读取速度提升 3–5 倍,且支持列裁剪 - 别忘了:
chunksize解决的是“读得进”,不是“算得快”——清洗逻辑写得低效,块再小也没用
chunksize 参数有用得多。










