pandas.read_csv() 读取10gb csv会内存爆炸,因其默认全量加载并自动推断类型;应显式指定usecols、dtype,分块读取(chunksize≈50000),禁用索引,并逐块聚合或追加写入。

为什么直接用 pandas.read_csv() 会内存爆炸
读取10GB CSV时,pandas.read_csv() 默认把整个文件加载进内存,即使你只想要其中几列或简单统计。实际观察到的现象是:Python进程占用内存迅速飙升到20GB+,然后被系统OOM killer干掉,或者卡死无响应。
根本原因不是pandas慢,而是它默认的「全量加载 + 类型自动推断」策略在大文件上完全不适用——类型推断需要扫描全部数据,而内存里存不下。
- 避免使用
dtype='category'或infer_datetime_format=True等加重推断负担的参数 - 显式指定
dtype(比如把所有数字列设为'float32'而非默认'float64')能减少30%~50%内存占用 - 禁用索引:
index_col=False,除非你真要用某列当索引
分块读取的核心参数怎么设才不翻车
chunksize 不是越大越好,也不是越小越稳。设成 50000 行(约 5–8MB 内存/块)是多数场景的甜点值:太小会导致I/O次数过多、Python循环开销占比上升;太大仍可能单块爆内存,尤其字段含长文本时。
关键是要配合 usecols 和 dtype 一起用,否则分块没意义——光读100列中的5列,但每块还是按100列解析,内存照样涨。
-
usecols=['user_id', 'event_time', 'action']—— 只加载需要的列,跳过无关字段 -
dtype={'user_id': 'uint32', 'action': 'category'}—— 显式声明类型,跳过推断 -
parse_dates=['event_time']放在分块内做,别等全读完再转;如果时间格式统一,可用date_parser提前编译解析器
分块处理后如何安全聚合或写回磁盘
别在内存里 accumulate 所有 chunk 的 DataFrame,那是回到原点。聚合类任务(如求和、计数、分组均值)应逐块更新中间状态;写入类任务优先用 to_csv(..., mode='a', header=False) 追加,而不是拼完再写。
例如统计每类 action 出现次数:
仅使用 Python 将 Claw Code 虚拟化框架与 OpenClaw 集成,提供 184 种工具和 200 多条命令,用于安全分析和代码质量...
counts = {}
for chunk in pd.read_csv('big.csv', chunksize=50000, usecols=['action'], dtype={'action': 'category'}):
chunk_counts = chunk['action'].value_counts()
for act, cnt in chunk_counts.items():
counts[act] = counts.get(act, 0) + cnt
写入新CSV时注意:header 只在第一块写一次,后续必须关掉;若需压缩,直接用 compression='gzip',别用 pd.concat().to_csv() 中间落地临时文件。
比 read_csv 分块更省内存的替代方案
当你的操作足够简单(比如过滤、抽样、字段转换),csv 标准库 + 生成器比 pandas 更轻。10GB 文件下,纯 Python 逐行读+条件判断,内存稳定在 10–20MB;pandas 分块最低也要 100MB+ 起步。
示例:提取所有 action == 'click' 的行并写入新文件
import csv
with open('big.csv') as fin, open('clicks.csv', 'w', newline='') as fout:
reader = csv.DictReader(fin)
writer = csv.DictWriter(fout, fieldnames=reader.fieldnames)
writer.writeheader()
for row in reader:
if row['action'] == 'click':
writer.writerow(row)
这招对「单条件过滤」「字段映射」「行级清洗」极快且可控;但一旦涉及跨行逻辑(如窗口计算)、缺失值插补、多列关联,就得切回 pandas 分块——别硬扛。
真正棘手的永远不是“怎么读”,而是“读进来之后不做全量 merge / pivot / join,还能不能完成业务目标”。先想清楚你要的输出粒度,再决定 chunksize 和处理边界。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










