我的知识记录

Python pandas多表合并concat merge详解

区分concat纵向拼接、merge按键关联、join按索引关联三种合并方式,覆盖Excel里常见的多sheet拼表、两表VLOOKUP场景。

场景痛点

Excel里想把三个月的表拼到一起,再用VLOOKUP把客户表的名称补到订单表,手动操作步骤多还容易错位。pandas里 concat 做纵向拼表,merge 做按键关联,等价于SQL的JOIN,几行代码搞定。

用到的库

pip install pandas

完整代码

import pandas as pd

def merge_demo():
# 订单表:两个月份的数据
orders_jan = pd.DataFrame({
"order_id": ["A001", "A002"],
"cust_id":  [1, 2],
"amount":   [1000, 2000],
})
orders_feb = pd.DataFrame({
"order_id": ["B001", "B002"],
"cust_id":  [1, 3],
"amount":   [1500, 800],
})

# 客户表
customers = pd.DataFrame({
"cust_id":  [1, 2, 3],
"cust_name": ["甲公司", "乙公司", "丙公司"],
"city":     ["北京", "上海", "深圳"],
})

# 1. concat:纵向拼表(上下拼)
all_orders = pd.concat([orders_jan, orders_feb], ignore_index=True)
print("拼接后订单:")
print(all_orders)

# 2. merge:按键关联,左连接订单和客户
merged = pd.merge(
all_orders,
customers,
on="cust_id",      # 两边都叫cust_id;不同列名用 left_on/right_on
how="left",        # left/inner/right/outer
)
print("\n关联客户后:")
print(merged)

# 3. 横向拼接(左右拼):索引对齐
extra = pd.DataFrame({"discount": [0.9, 1.0, 0.95, 1.0]})
side_by_side = pd.concat([merged, extra], axis=1)
print("\n横向拼上折扣列:")
print(side_by_side)

if __name__ == "__main__":
merge_demo()

代码讲解

  • pd.concat([df1, df2], ignore_index=True) 纵向拼表,要求列名一致;ignore_index=True 重新编号行号,避免重复索引。
  • pd.concat(..., axis=1) 横向拼表,按索引对齐,索引对不上会产生NaN。
  • pd.merge(df1, df2, on="cust_id", how="left") 等价于SQL的LEFT JOIN。how="inner" 是只保留匹配上的,outer 全保留。
  • 两表关联字段名不同时,用 left_on="订单客户号", right_on="客户ID"
  • merge后同名非关联列会自动加 _x_y 后缀,用 suffixes=("_订单", "_客户") 指定。

运行结果

控制台依次打印拼接后的4行订单、关联客户后的结果(含cust_name和city)、横向拼上discount列后的完整表。A001对应甲公司北京,B002对应丙公司深圳。

注意事项

  • merge前先 df1["key"].is_unique 确认关联键是否唯一,一对多会导致结果行数膨胀。
  • 两表key类型不一致(一边int一边str)会匹配不上,merge前统一 astype(str)
  • 大表merge前先排序并设置索引,df.set_index("key").join(df2) 比merge快。
  • concat纵向拼表时列顺序要一致,否则会出现大量NaN,建议先 df = df[标准列顺序] 对齐。

Python pandas多表合并concat merge详解

标签:

更新时间:2026-09-14 20:57:29

上一篇:Python pandas时间日期处理教程

下一篇:Python pandas数据清洗去重去空实战