Skip to content

Pandas Merge & Join:像 SQL 一样稳妥地做连接

Updated on

做表连接最容易踩坑:键不对导致行数暴增或丢失,常见的是滥用 how=\"inner\",却很少用 validateindicator 进行自检。

PAS 视角:

  • 问题: 键错位让 merge 悄悄重复或遗漏数据。
  • 激化: 排查重复后缀、意外的笛卡尔积或缺失行会耗费时间。
  • 解决: 显式定义键,选择正确的 how,并用 validate/indicator 早发现问题。

Join 速查表

类型 (how)保留左表?保留右表?常见用途
inner✅ 仅匹配✅ 仅匹配交集
left✅ 全部🚫 仅匹配保留左表并补充
right🚫 仅匹配✅ 全部保留右表(少用,通常交换顺序即可)
outer✅ 全部✅ 全部全连接,缺失填 NaN

示例数据

import pandas as pd
 
orders = pd.DataFrame({
    "order_id": [1, 2, 3],
    "customer_id": [100, 101, 102],
    "amount": [50, 80, 60],
})
 
customers = pd.DataFrame({
    "customer_id": [100, 101, 103],
    "name": ["Ada", "Ben", "Cara"],
    "segment": ["pro", "basic", "pro"],
})

基本列键 merge

result = orders.merge(
    customers,
    on="customer_id",
    how="left",
    validate="many_to_one",  # 期望维表
    indicator=True,          # 审核覆盖
)
  • validate 捕捉意外的基数(many_to_many 是警告信号)。
  • indicator 添加 _merge 列显示 left_only/right_only/both
  • suffixes=("_order", "_cust") 避免列名覆盖。

键名不同的连接

payments = pd.DataFrame({
    "cust_id": [100, 100, 103],
    "last_payment": ["2025-05-20", "2025-05-27", "2025-05-21"],
})
 
orders.merge(
    payments,
    left_on="customer_id",
    right_on="cust_id",
    how="left",
)

基于索引的 join

customers_idx = customers.set_index("customer_id")
orders.join(customers_idx, on="customer_id", how="left")
  • 右表的键在索引里时 .join 方便。
  • 多级索引可用 on=["level_0", "level_1"] 或先对齐索引。

处理重复与重叠

# Merge 前检查重复键
dupes = customers["customer_id"].value_counts()
problem_keys = dupes[dupes > 1]
 
# Merge 后检查意外膨胀
exploded = orders.merge(customers, on="customer_id", how="inner", validate="many_to_many")
  • 如果本该 many_to_one 行数却增加,检查维表是否需 drop_duplicates(subset=keys)

一次合并多条指标

agg = (
    orders.groupby("customer_id", as_index=False)
          .agg(total_amount=("amount", "sum"), orders_count=("order_id", "count"))
)
 
customers.merge(agg, on="customer_id", how="left")

先聚合再 merge,避免对原始交易表进行多次连接。


调试清单

症状检查
行数暴增查看 _mergevalidate 设为期望的基数。
Merge 后缺行改用 how="left"how="outer";对齐键的 dtype。
匹配错误确保键的 dtype 相同(字符串 vs 整数)。
列名冲突设置 suffixes 防止覆盖。

相关指南


关键要点

  • 有目的地选择 join 类型;丰富数据时 left 最安全。
  • validateindicatorsuffixes 及早发现问题。
  • 对齐键和值类型,必要时先去重维表以避免行数爆炸。