merge表连出全NaN的根本原因是关联字段名或类型不一致,需显式指定left_on/right_on并统一dtype;concat需注意索引对齐、列匹配及axis参数;混用时须检查重复与key唯一性,并为连接键设索引提升性能。

merge 用不对,表连出来全是 NaN
根本原因是 merge 默认按列名严格匹配,但两表的关联字段名不一致(比如左表叫 "user_id",右表叫 "id"),或类型不一致(如一端是 int64,另一端是 object 字符串)。这时候 merge 不报错,但所有连接结果都是 NaN。
- 务必先检查关联列:用
df1["col"].dtype和df2["col"].dtype确认类型一致;用df1.columns和df2.columns对比字段名 - 字段名不同时,显式指定:
pd.merge(df1, df2, left_on="user_id", right_on="id") - 类型不一致时,优先转成相同类型,比如:
df2["id"] = df2["id"].astype("int64"),别依赖自动转换 -
how="inner"是默认值,如果想保留左表全部行,得写明how="left",否则容易漏数据
concat 堆叠后索引乱、列对不齐
concat 不是“粘一起就完事”,它默认按索引对齐列。如果两张表列名不完全一致,缺失列会自动补 NaN;如果索引是默认 RangeIndex 但长度不同,拼完索引会重复或跳号,后续 groupby 或取数容易出错。
- 列对不齐?加参数
ignore_index=True重置行索引,避免拼接后索引混乱 - 列不全?加
sort=False保持原始列顺序,加join="outer"(默认)保留所有列,或join="inner"只留共有的列 - 想按列方向拼(即横向合并)?必须明确写
axis=1,且两表行数必须严格相等,否则报ValueError: Shape mismatch - 常见误用:
pd.concat([df1, df2], axis=0)却没重置索引,导致.iloc[100]实际取到的是 df2 的第 0 行
merge 和 concat 混用时的隐性陷阱
实际业务中常先 concat 多个来源的明细表,再 merge 维度表。但若 concat 后没去重或没处理重复索引,merge 时可能一对多爆炸式膨胀——比如 1 个用户在 concat 后出现 3 次,再和用户维度表 merge,就变成 3 行重复数据。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- concat 后立刻检查:
df_combined.duplicated().sum()和df_combined.index.is_unique - merge 前确认连接键唯一性:对维度表,用
dim_df["key"].is_unique;对事实表,fact_df["key"].duplicated().any()要为False(除非本就是多对一场景) - 不要省略
validate参数:比如pd.merge(fact, dim, on="user_id", validate="m:1"),pandas 会主动校验并报错,比事后 debug 强得多
性能差不是数据大,是 key 没设索引
当 merge 的左表或右表超过 10 万行,且连接字段没做预处理,merge 会退化成嵌套循环,耗时飙升。这不是 pandas 本身慢,而是没利用哈希表加速。
立即学习“Python免费学习笔记(深入)”;
- 对高频连接的字段,提前设为索引:
df.set_index("user_id", inplace=True),再用join(底层更优)替代merge - 或者用
pd.merge(..., sort=False)关掉默认排序——排序本身在大数据量下开销不小 - 内存吃紧?加
copy=False(仅当确定不修改原 df 时),避免冗余拷贝 - 注意:
concat本身不触发计算,但后面紧跟merge或groupby时,前面 concat 的低效操作会被放大
最常被跳过的一步:merge 前没验证 key 是否为空、是否含不可见字符(比如空格、\u200b)。这类问题不会报错,但连出来的结果永远少几条,查半天才发现是 "123 " 和 "123" 对不上。

















