项目5:数据合并与连接
数据集:订单表+客户表+商品表 | 难度:进阶 | 预计用时:60分钟
学习目标
- 掌握concat纵向和横向拼接数据
- 理解merge的四种连接方式(inner/left/right/outer)
- 学会指定连接键进行表连接
- 了解join方法的使用场景
知识点讲解
1. concat拼接
concat就像把几张纸粘在一起,可以纵向粘(增加行),也可以横向粘(增加列)。
# 纵向拼接(增加行):把两个结构相同的表上下叠起来
pd.concat([df1, df2], axis=0)
# 横向拼接(增加列):把两个表左右并排
pd.concat([df1, df2], axis=1)
# 忽略原来的行索引,重新编号
pd.concat([df1, df2], axis=0, ignore_index=True)
2. merge连接
merge就像SQL里的JOIN,根据两个表共有的列(连接键)把数据拼在一起。
# 基本用法:按共有的列名自动连接
pd.merge(df1, df2, on='客户ID')
# 左右表的连接键名不同
pd.merge(df1, df2, left_on='客户编号', right_on='客户ID')
3. 四种连接方式
这是merge最重要的概念,用维恩图理解最直观:
- inner(内连接):只保留两个表都有的记录(交集)。最严格,可能丢失数据。
- left(左连接):保留左表所有记录,右表没有的填NaN。最常用!
- right(右连接):保留右表所有记录,左表没有的填NaN。
- outer(外连接):保留两个表所有记录(并集)。最宽松,不会丢失数据。
# 内连接:只保留两边都有的客户
pd.merge(orders, customers, on='客户ID', how='inner')
# 左连接:保留所有订单,没有客户信息的填NaN
pd.merge(orders, customers, on='客户ID', how='left')
# 右连接:保留所有客户,没有订单的也保留
pd.merge(orders, customers, on='客户ID', how='right')
# 外连接:保留所有订单和所有客户
pd.merge(orders, customers, on='客户ID', how='outer')
4. join方法
join是merge的简化版,默认按索引连接,适合索引已经对齐的情况:
# 按索引连接
df1.join(df2, how='left')
# 按指定列连接(需要设置列为索引)
df1.set_index('客户ID').join(df2.set_index('客户ID'))
5. 连接后的列名冲突
如果两个表有同名的非连接列,pandas会自动加后缀区分:
# 自定义后缀
pd.merge(df1, df2, on='客户ID', suffixes=('_订单', '_客户'))
完整代码示例
import pandas as pd
# 读取三个数据表
orders = pd.read_csv('orders_table.csv')
customers = pd.read_csv('customers_table.csv')
products = pd.read_csv('products_table.csv')
print("=== 订单表 ===")
print(orders)
print("\n=== 客户表 ===")
print(customers)
print("\n=== 商品表 ===")
print(products)
# ===== concat纵向拼接示例 =====
# 假设有两批订单数据,结构相同
batch1 = orders[orders['订单号'].isin(['O001', 'O002'])]
batch2 = orders[orders['订单号'].isin(['O003', 'O004'])]
all_orders = pd.concat([batch1, batch2], axis=0, ignore_index=True)
print("\n=== concat拼接后的订单 ===")
print(all_orders)
# ===== merge连接:订单 + 客户 =====
print("\n=== 订单与客户信息(左连接) ===")
order_customer = pd.merge(orders, customers, on='客户ID', how='left')
print(order_customer)
# ===== merge连接:订单 + 商品 =====
print("\n=== 订单与商品信息(左连接) ===")
order_product = pd.merge(orders, products, on='商品ID', how='left')
print(order_product)
# ===== 三表连接:订单 + 客户 + 商品 =====
print("\n=== 三表连接后的完整信息 ===")
full = pd.merge(orders, customers, on='客户ID', how='left')
full = pd.merge(full, products, on='商品ID', how='left')
print(full)
# ===== 四种连接方式对比 =====
print("\n=== inner连接(只保留两边都有的) ===")
inner_result = pd.merge(orders, customers, on='客户ID', how='inner')
print(inner_result)
print("\n=== outer连接(保留所有记录) ===")
outer_result = pd.merge(orders, customers, on='客户ID', how='outer')
print(outer_result)
# ===== 连接键名不同的情况 =====
# 假设客户表里的列叫'编号'而不是'客户ID'
customers2 = customers.rename(columns={'客户ID': '编号'})
print("\n=== 连接键名不同时 ===")
merged = pd.merge(orders, customers2, left_on='客户ID', right_on='编号', how='left')
print(merged)
实操步骤
- 分别读取orders_table.csv、customers_table.csv、products_table.csv
- 用
head()查看三个表的结构和关键列 - 用
pd.concat()将两个结构相同的DataFrame纵向拼接 - 用
pd.merge()将订单表和客户表按"客户ID"左连接 - 用
pd.merge()将订单表和商品表按"商品ID"左连接 - 尝试将三表依次连接,得到包含订单、客户、商品信息的完整表
- 分别用inner、left、right、outer四种方式连接,观察结果差异
- 练习left_on和right_on,处理连接键名不同的情况
配套数据集
orders_table.csv(订单表)
订单号,客户ID,商品ID,数量,订单金额
O001,C001,P001,2,1998
O002,C002,P003,1,599
O003,C001,P002,3,897
O004,C003,P001,1,999
O005,C004,P002,2,598
customers_table.csv(客户表)
客户ID,客户姓名,客户等级,注册城市
C001,张三,金牌,广州
C002,李四,银牌,深圳
C003,王五,铜牌,北京
C006,赵六,金牌,上海
products_table.csv(商品表)
商品ID,商品名称,商品类别,单价
P001,智能手机,电子产品,999
P002,蓝牙耳机,电子产品,299
P003,运动手表,穿戴设备,599
P004,平板电脑,电子产品,1999
交互式练习题
0/7
第1题
选择题
将两个结构相同的DataFrame纵向拼接(增加行),应该用?
答案解析
concat用于拼接,axis=0表示纵向(增加行),axis=1表示横向(增加列)。
第2题
选择题
merge中保留左表所有记录,右表没有匹配的填NaN,这是哪种连接?
答案解析
left(左连接)保留左表所有记录,右表没有匹配的行填NaN。这是最常用的连接方式。
第3题
选择题
merge中只保留两个表都有的记录(交集),这是哪种连接?
答案解析
inner(内连接)只保留两个表都有的记录,相当于集合的交集。
第4题
判断题
outer连接会保留两个表的所有记录,不会丢失任何数据。
答案解析
outer(外连接)保留两个表的所有记录,相当于集合的并集,不会丢失数据。
第5题
填空题
左右表连接键名不同时,应使用
pd.merge(df1, df2, left_on='A', right_on='B', how='left'),其中left_on指定表的连接键。答案解析
left_on指定左表的连接键列名,right_on指定右表的连接键列名。
第6题
选择题
join方法默认按什么进行连接?
答案解析
join()默认按索引进行连接,适合索引已经对齐的情况。
第7题
选择题
pd.concat([df1, df2], axis=1) 的作用是?
答案解析
axis=1表示横向拼接(增加列),axis=0表示纵向拼接(增加行)。
0/7
项目小结
本项目我们学习了数据合并与连接的核心技能:
- 用
pd.concat()纵向(axis=0)或横向(axis=1)拼接数据 - 用
pd.merge()按连接键将两个表连接 inner:只保留两边都有的记录(交集)left:保留左表所有记录,最常用right:保留右表所有记录outer:保留所有记录(并集)- 用
left_on和right_on处理连接键名不同的情况 - 用
join()按索引快速连接
数据合并是实际工作中最常见的操作之一,因为业务数据通常分散在多个表中。掌握merge和concat,你就能把分散的数据整合成完整的分析视图。