chunksize应根据内存实测反推:先用nrows=10000试读并计算memory_usage,再按目标内存(如500MB)推算合理值;需配合dtype指定、编码优化、流式聚合等策略避免爆内存和性能退化。

chunksize参数到底传什么值才不爆内存
直接给chunksize=10000不是万能解法——它只控制行数,不控制实际内存占用。真正决定内存的是每行字段数、字符串长度、数据类型(比如全object列比int32吃得多得多)。建议先用pd.read_csv(filename, nrows=10000)试读一小段,用df.memory_usage(deep=True).sum()算出这1万行占多少MB,再按目标内存(比如500MB)反推合理chunksize。
- 避免凭空设
chunksize=100000,尤其含长文本或高基数分类列时,可能单块就超2GB - 如果文件有明显稀疏列(如大量
NaN),加dtype显式指定类型(如{'user_id': 'category', 'score': 'float32'})比依赖自动推断省一半以上内存 - Windows下Python默认使用UTF-8-sig编码读取,若文件是纯UTF-8,显式写
encoding='utf-8'可避免BOM解析开销
用for循环读chunk时为什么越跑越慢甚至卡死
常见陷阱是把每个chunk直接pd.concat([dfs])累积到一个大列表里——这会导致Python频繁申请新内存、复制旧数据,GC压力陡增。更糟的是,如果在循环里做chunk.to_sql(...)但没设if_exists='append'或事务控制,数据库连接可能堆积未提交事务。
- 处理逻辑尽量在单个
chunk内闭环:过滤→计算→写磁盘/数据库,别攒着等最后合并 - 写CSV用
chunk.to_csv('out.csv', mode='a', header=False),首次写加header=True,后续mode='a'追加 - 写数据库时,用
chunk.to_sql('table', con, if_exists='append', index=False),并确保con是带连接池的引擎(如SQLAlchemy的create_engine(..., pool_size=5))
read_csv(chunksize=...)返回的对象不是DataFrame
pd.read_csv(..., chunksize=N)返回的是TextFileReader对象,本质是可迭代器,不是DataFrame。直接对它调.shape或.head()会报AttributeError,必须用for chunk in reader:或next(reader)取出来才是真正的DataFrame。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 错误示范:
reader = pd.read_csv('x.csv', chunksize=5000); print(reader.shape)→ 报错 - 正确用法:
for chunk in pd.read_csv('x.csv', chunksize=5000): process(chunk) - 想预览第一块?用
first_chunk = next(pd.read_csv('x.csv', chunksize=5000)),注意这会消耗迭代器第一个元素
分块读取后如何做全局统计(比如全文件最大值、唯一值个数)
不能对每个chunk单独算max()再取最大——浮点精度、时区、类别顺序都可能导致结果偏差。必须用流式聚合策略:对数值列维护当前极值,对分类型字段用pd.concat([chunk[col].unique() for chunk in reader]).unique()虽可行但内存不可控;更稳的是用collections.Counter或Dask的delayed机制。
- 求全局最大值:
global_max = float('-inf'); for chunk in reader: global_max = max(global_max, chunk['col'].max()) - 求唯一值个数(内存敏感):
seen = set(); for chunk in reader: seen.update(chunk['col'].dropna().astype(str)); len(seen),注意astype(str)统一类型避免hash冲突 - 涉及多列联合去重或复杂聚合(如分位数),别硬扛,换
dask.dataframe.read_csv,它原生支持延迟计算和块间协调
实际跑起来你会发现,最耗时间的往往不是读取本身,而是类型自动推断和缺失值标记(na_values匹配)。如果明确知道空值只用''和'NULL'表示,务必传na_values=['', 'NULL']并设keep_default_na=False,能提速30%以上。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










