应避免用 pd.read_csv() 一次性读取大文件,而需分块读取(chunksize)、显式指定 dtype、流式写入,并慎用 Dask。

直接用 pd.read_csv() 读大文件必爆内存
这不是 Pandas 的 bug,而是设计使然:它默认把整张表加载进内存,构建完整 DataFrame。一个 8GB 的 CSV 文件,实际内存占用常超 20GB——因为字符串列默认是 object 类型,每条记录都存指针;数值列默认用 int64/float64,哪怕你只存 0–100 的 ID;还有索引、元数据、临时副本……全堆在一起。
别等报错再改。只要文件 >500MB,就该放弃一次性读取。最稳妥的起点是加 chunksize 参数,让它返回一个可迭代的 TextFileReader 对象,而不是 DataFrame。
-
chunksize=50000是较通用的起始值,机械硬盘可调小(如 10000),SSD 或 NVMe 可略放大(如 100000) - 不要在循环里反复调用
pd.read_csv()—— 那会重复解析 header、推断类型,开销更大 - 如果只是想看前几行调试,用
nrows=1000,比chunksize更轻量
dtype 不显式指定,内存浪费至少翻倍
Pandas 自动推断类型很“保守”:看到一列全是数字,就给 int64;看到几个空值,就升成 float64;遇到重复字符串,一律 object。而真实数据往往远没那么“宽”。比如用户 ID 实际最大值是 2 亿,int32 就够(上限约 21 亿);城市名只有 300 个不同值,category 类型能压缩到 1/10 内存。
正确做法是先采样分析,再固化类型:
立即学习“Python免费学习笔记(深入)”;
从 CSV 数据集生成图数据库加载器和三元组映射。将表格 CSV 数据转换为图数据库可直接使用的节点、边和三元组。
- 用
pd.read_csv(filename, nrows=10000)快速读一小部分 - 跑
df.dtypes和df.memory_usage(deep=True)看哪列最“肥” - 对整数列,优先试
"int32"或"uint32";浮点列试"float32";高频重复字符串列强制"category" - 传给
pd.read_csv()的dtype字典必须覆盖所有要读的列,漏掉的仍按默认推断
边读边写,别攒 list.append()
常见反模式:用 results = [] 收集每块处理结果,最后 pd.concat(results)。这等于在内存里同时存 N 个 DataFrame 副本——第 1 块进来,占 100MB;第 2 块进来,系统得再分配 100MB,旧的还没释放;到第 50 块,内存早炸了。
真正省内存的做法是“流式落盘”:
- 打开输出文件用
open(..., "w", newline=""),配csv.writer或pd.DataFrame.to_csv(..., mode="a", header=False) - 每块处理完立刻写入,不保留原始 chunk 或中间结果
- 若需聚合(如统计每个用户的点击数),用
collections.Counter或字典累加,只存键值对,不存原始行 - 避免在循环里调
df.groupby().size()—— 它会为每块建新 DataFrame;改用chunk[col].value_counts()后合并 Counter
dd.read_csv() 不是银弹,配置错反而更慢
Dask 确实能绕过内存限制,但它不是 Pandas 的“无缝升级版”。dd.read_csv() 默认按字节切分(blocksize="25MB"),可能把一行硬生生截断;类型推断只采样开头几行,若数据分布不均(比如前 100 行全空,第 10000 行才出现字符串),后续分区解析直接失败。
要用 Dask 稳住,三件事不能省:
- 显式设
blocksize="16MB"(尤其在 HDD 或网络存储上) - 必须传
dtype字典,且所有列都要覆盖,不能依赖自动推断 - 中文路径或 GBK 编码文件,务必加
encoding="gbk";含 BOM 的 UTF-8 加encoding="utf-8-sig" - 首次读完建议立刻转成 Parquet:
ddf.to_parquet("data.parq"),后续全用dd.read_parquet()—— 列式存储 + 谓词下推,性能差距可达 3–5 倍
最易被忽略的一点:Dask 的 .compute() 是“引爆点”。任何操作只要触发 .compute(),就会把整个计算图拉进内存。所以别在调试时随手敲 ddf.head() —— 它本质就是 .compute() 前 5 行,一样会卡死。

















