首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >pandas merge 之后行数暴涨、全是 NaN、dtype 变了?9 个对照表

pandas merge 之后行数暴涨、全是 NaN、dtype 变了?9 个对照表

原创
作者头像
用户6689525
发布于 2026-10-05 10:12:07
发布于 2026-10-05 10:12:07
140
举报

结论先行:merge 出问题,八成不是语法错,而是连接键的重复值、dtype 不一致、以及 how 的默认值这三件事。本文用 9 组「症状 → 原因 → 修法」对照表,把 merge 的坑一次说清。

坑 1:合并后行数暴涨(笛卡尔积)

症状:左表 1000 行,右表 500 行,merge 完变 5000 行。

原因:连接键在右表有重复值,一对多会逐行展开。

代码语言:python
复制
df_right["key"].duplicated().sum()

r = df_right.drop_duplicates(subset="key", keep="last")
df.merge(r, on="key", how="left")

df.merge(r, on="key", how="left", validate="many_to_one")

坑 2:合并后全是 NaN

症状:明明键值一样,右表的列全是 NaN。

原因:dtype 不一致——左表是 int64,右表是从 CSV 读进来的 str,'1001' != 1001。

代码语言:python
复制
df_left["key"].dtype, df_right["key"].dtype   # int64 vs object
df_right["key"] = df_right["key"].astype(df_left["key"].dtype)

场景

检查点

从 CSV 读

数字键是否被读成字符串

有前导零

编号 00123 会被当成 123

空值

键里混了 None / np.nan

坑 3:列名冲突变成 _x / _y

症状:合并后出现 score_x、score_y,不知道哪个是自己的。

原因:两表有同名非键列,pandas 自动加后缀。

代码语言:python
复制
r = df_right.rename(columns={"score": "score_2025"})
df.merge(r, on="key", how="left")

坑 4:how 默认 inner,数据被悄悄丢了

症状:左表 1000 行,merge 完只剩 800 行。

原因:how 的默认值是 'inner',只保留交集。

how

结果

inner(默认)

只留两表都有的键

left

保留左表全部,右表缺失填 NaN

right

保留右表全部

outer

全部保留

建议:显式写 how=,别依赖默认值。

坑 5:on 与索引混用

症状:KeyError: 'key',或合并结果不对。

原因:键在索引上而不是列里,得用 left_index=True / right_index=True。

代码语言:python
复制
df.merge(r, left_on="key", right_index=True, how="left")

坑 6:int 列合并后变成 float

症状:原本是整数的 age 列,合并后变成 18.0。

原因:该行没匹配上,填入了 NaN,而 NaN 是浮点,整列被向上转型成 float64。

代码语言:python
复制
df["age"] = df["age"].astype("Int64")

坑 7:多键合并只匹配了一部分

症状:用 on=["a","b"] 合并,行数比预期少。

原因:多键是按组合匹配的,任一列对不上就整行不匹配。

代码语言:python
复制
merged = df.merge(r, on=["a", "b"], how="left", indicator=True)
merged["_merge"].value_counts()   # left_only 有多少

indicator=True 会加一列 _merge,直接告诉你每行是 both 还是 left_only。

坑 8:suffixes 没设,后缀撞车

症状:多次合并后列名变成 score_x_x。

修法:每次合并显式给后缀。

代码语言:python
复制
df.merge(r, on="key", suffixes=("", "_right"), how="left")

坑 9:大表 merge 慢、内存爆

症状:几百万行合并时卡死或 MemoryError。

原因:merge 前没做三件事——降 dtype、去无用列、去重。

代码语言:python
复制
r2 = r[["key", "val"]].copy()
r2["key"] = r2["key"].astype("category")
df.merge(r2, on="key", how="left")

速查小结

症状

第一怀疑对象

行数暴涨

右表键有重复(笛卡尔积)

全是 NaN

键 dtype 不一致

行数变少

how 默认 inner

出现 _x/_y

同名列冲突

int 变 float

NaN 导致向上转型

慢 / 爆内存

未降 dtype、未去冗余列

记住三句话:merge 前先查键的 dtype 与重复值;how 一定显式写;加上 validate= 和 indicator=True**,让 pandas 替你把错报出来**。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 坑 1:合并后行数暴涨(笛卡尔积)
  • 坑 2:合并后全是 NaN
  • 坑 3:列名冲突变成 _x / _y
  • 坑 4:how 默认 inner,数据被悄悄丢了
  • 坑 5:on 与索引混用
  • 坑 6:int 列合并后变成 float
  • 坑 7:多键合并只匹配了一部分
  • 坑 8:suffixes 没设,后缀撞车
  • 坑 9:大表 merge 慢、内存爆
  • 速查小结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档