pd.merge()内存暴增源于读取、索引、复制三重开销:未用usecols/dtype优化、key列未去重建索引、时间列未解析致object膨胀;merge时全量加载、双哈希表、NaN填充、笛卡尔组合使峰值达原始2–4倍;del不释放、Jupyter缓存、视图引用加剧问题。

因为 pd.merge() 默认全量加载、重建索引、填充 NaN,并对字符串列做对象指针复制——三者叠加会让内存峰值达到原始数据总和的 2–4 倍,不是“翻倍”,是“暴增”。
merge 前就已吃掉大量内存
很多人以为内存爆炸发生在 merge 执行中,其实从 pd.read_csv() 开始就埋了雷:
-
usecols没设:读入了所有列,哪怕只用其中两列做连接 -
dtype没压:整数列默认int64,字符串列全是object(每个值单独分配堆内存 + 引用指针) - key 列没提前去重或设
index:merge 内部会为左右表各建一次哈希索引,重复建索引 = 重复内存开销 - 未用
parse_dates解析时间列:时间列退化成object,内存占用飙升数倍
merge 过程中悄悄复制了三份数据
你只写了 result = pd.merge(left, right, on="id"),但 Pandas 在背后做了这些事:
- 把
left和right全拷进内存(即使你刚删过它们,只要变量名还活着,就还在) - 为每张表构建临时哈希表(key → 行号映射),这本身就要额外内存
- 匹配后逐行构造新行:NaN 填充、列对齐、类型提升(如
int64+float32→float64) - 若 key 有重复,还会隐式生成笛卡尔组合行——100 × 200 就是 2 万行,每行都占内存
merge 后内存还不释放?那是引用没断
结果出来后 del left, right 不一定管用,尤其在 Jupyter 或链式调用里:
立即学习“Python免费学习笔记(深入)”;
-
result是视图(view)而非副本(copy),可能仍持有对原始块的引用 -
df.loc[...]或df.query(...)后直接 merge,返回的仍是视图,拖住整个原始 DataFrame - 没显式调用
gc.collect():CPython 在 Windows 下 GC 不够激进,del只是解绑名字,不等于立即回收 - 用了
.copy()但写在 merge 之后?晚了——膨胀已经发生;应写成result = pd.merge(...).copy()
真正卡死你的从来不是 merge 函数本身
而是你没意识到:重复键让行数指数级发散、object 字符串列在内存里是“散装”的、del 不等于释放、Jupyter 的变量缓存比你想象中更顽固。这些点任何一个漏掉,pd.merge() 就会从工具变成定时炸弹。


















