应避免字符串列默认为object类型,改用category、usecols跳过、向量化操作、分块处理、流式匹配及polars scan_csv等方法节省内存。

字符串列是内存杀手,别让它默认用 object
当你用 pd.read_csv() 读一个含长文本(如日志、评论、商品描述)的 CSV,pandas 默认把所有字符串列识别为 object 类型——这不是“字符串”,而是一堆指向 Python 字符串对象的指针数组。100 万行文本列,object 可能吃掉 800MB+ 内存,远超原始文件大小。
真正该做的是:明确告诉 pandas 这列你只用来过滤或简单匹配,不需要全量驻留内存:
- 若该列唯一值极少(比如状态码、分类标签),强制设
dtype={'label': 'category'} - 若只是临时清洗(如去空格、正则替换),加
keep_default_na=False避免额外构建 NaN 映射表 - 完全不用这列?直接用
usecols跳过它,比后续del df['text']省得多
别用 .apply() 处理大文本列,改用向量化或分块
df['text'].apply(clean_text) 看起来干净,但背后是 Python 解释器逐行调用函数,每行都新建字符串对象,GC 压力巨大;更糟的是,如果 clean_text 返回新字符串,原字符串不会立刻释放,内存峰值可能翻倍。
替代方案更稳:
- 优先用
str.replace()、str.lower()等原生向量化方法,它们复用底层内存池 - 若必须用自定义逻辑(如复杂正则提取),改用
chunksize分批处理:for chunk in pd.read_csv(..., chunksize=5000),每批处理完立刻del chunk - 极端情况(如需 spaCy 解析),把文本列先
to_list()转成纯 Python list,再传给 NLP 库——绕过 pandas 的 object 列管理开销
模糊匹配时禁止构造全量组合 DataFrame
想对 50 万条产品标题做两两相似度计算?写 itertools.combinations(df['title'], 2) 然后塞进 pd.DataFrame(),等于在内存里造一个 1250 亿行的中间表——哪怕你只想要 ratio ≥ 95 的结果,也早就 OOM 了。
正确做法是彻底放弃 DataFrame 中间态:
- 用标准库
csv模块流式写入:with open("matches.csv", "w") as f,边算边写 - 提前过滤:先用
str.len()或str.contains()快速筛掉长度差 >50% 的候选对,减少 70%+ 计算量 - 换轻量库:用
thefuzz替代fuzzywuzzy(后者有已知引用泄漏),并显式控制processor=None避免自动 lower/strip 带来的重复字符串对象
Polars scan_csv + select 是处理大文本列的底线配置
如果你的文本列不参与计算,只是偶尔 grep 或导出,pl.scan_csv() 加 .select() 是目前最省内存的路径。它根本不会把文本列加载进内存,只在真正需要时(比如 .filter(pl.col("text").str.contains("error")))才按需解码对应块。
关键点只有两个:
- 必须用
scan_csv,不是read_csv;后者仍是 eager 模式,照样爆 -
.select()要放在filter之前,否则 Polars 不会下推列裁剪,文本列仍会被整列读取
真正卡住人的,从来不是“怎么算得快”,而是“怎么让不该进内存的东西,一步都不进来”。文本列尤其如此——它长得像数据,但多数时候只是索引或标记,别当真。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











