揭秘数据合并的秘密:一文掌握一对一、多对一、多对多合并技巧与实战!

[外链图片转存中…(img-lqsnbbbB-1719886562804)]

使用pd.merge()合并

  • 类似 MySQL 中表和表直接的合并
  • merge与concat的区别在于,merge需要依据某一共同的行或列来进行合并
  • 使用pd.merge()合并时,会自动根据两者相同column名称的那一列,作为key来进行合并
  • 每一列元素的顺序不要求一致

1. 一对一合并

df1 = pd.DataFrame({
    "name":["张三","李四","王五"],
    "id":[1,2,3],
    "age":[22,33,44],
})
df2 = pd.DataFrame({
    "id":[2,3,4],
    "sex":["男","女","男"],
    "job":["Saler","CEO","Programer"]
})
display(df1,df2)
nameidage
0张三122
1李四233
2王五344
idsexjob
02Saler
13CEO
24Programer
# 依据某一共同的列来进行合并
pd.merge(df1,df2)
nameidagesexjob
0李四233Saler
1王五344CEO
df1.merge(df2)
nameidagesexjob
0李四233Saler
1王五344CEO

2. 多对一合并

df3 = pd.DataFrame({
    "name":["张三","李四","王五"],
    "id":[1,2,2],
    "age":[22,33,44],
})
df4 = pd.DataFrame({
    "id":[2,3,4],
    "sex":["男","女","男"],
    "job":["Saler","CEO","Programer"]
})
display(df1,df2)
nameidage
0张三122
1李四233
2王五344
idsexjob
02Saler
13CEO
24Programer
df3.merge(df4)
nameidagesexjob
0李四233Saler
1王五244Saler

3. 多对多合并

df5 = pd.DataFrame({
    "name":["张三","李四","王五"],
    "id":[1,2,2],
    "age":[22,33,44],
})
df6 = pd.DataFrame({
    "id":[2,2,4],
    "sex":["男","女","男"],
    "job":["Saler","CEO","Programer"]
})
display(df5,df6)
nameidage
0张三122
1李四233
2王五244
idsexjob
02Saler
12CEO
24Programer
df5.merge(df6)
nameidagesexjob
0李四233Saler
1李四233CEO
2王五244Saler
3王五244CEO

4. key的规范化

  • 使用 on= 显示指定哪一列为key,当2个DataFrame有多列相同时使用
df1 = pd.DataFrame({
    "id":[1,2,3],
    "name":["张三","李四","王五"],
    "age":[22,33,44],
})
df2 = pd.DataFrame({
    "id":[2,3,4],
    "name":["男","女","男"],
    "job":["Saler","CEO","Programer"]
})
display(df1,df2)
idnameage
01张三22
12李四33
23王五44
idnamejob
02Saler
13CEO
24Programer
# 如果有多列名称相同,需要指定一列作为连接的字段
df1.merge(df2,on="id")
idname_xagename_yjob
02李四33Saler
13王五44CEO
  • 使用left_on和right_on指定左右两边的列作为key,当左右两边的key都不想等时使用
df1 = pd.DataFrame({
    "id":[1,2,3],
    "name":["张三","李四","王五"],
    "age":[22,33,44],
})
df2 = pd.DataFrame({
    "id2":[2,3,4],
    "sex":["男","女","男"],
    "job":["Saler","CEO","Programer"]
})
display(df1,df2)
idnameage
01张三22
12李四33
23王五44
id2sexjob
02Saler
13CEO
24Programer
# 如果没有相同列名,则需要使用left_on,right_on来分别指定2个表中的不同列作为连接的字段
df1.merge(df2,left_on="id",right_on="id2")
idnameageid2sexjob
02李四332Saler
13王五443CEO
  • 当左边的列和右边的index相同的时候,使用right_index=True
df1 = pd.DataFrame({
    "id":[1,2,3],
    "name":["张三","李四","王五"],
    "age":[22,33,44],
})
df2 = pd.DataFrame({
    "id2":[2,3,4],
    "sex":["男","女","男"],
    "job":["Saler","CEO","Programer"]
})
display(df1,df2)
idnameage
01张三22
12李四33
23王五44
id2sexjob
02Saler
13CEO
24Programer
# 可以使用行索引作为连接的字段
df1.merge(df2,left_index=True,right_index=True)
idnameageid2sexjob
01张三222Saler
12李四333CEO
23王五444Programer
# 左边使用索引,右边使用列名进行匹配
df1.merge(df2,left_index=True,right_on="id2")
idnameageid2sexjob
03王五442Saler

5. 内合并和外合并

  • 内合并:只保留两者都有的key(默认模式)
df1 = pd.DataFrame({
    "id":[1,2,3],
    "name":["张三","李四","王五"],
    "age":[22,33,44],
})
df2 = pd.DataFrame({
    "id":[2,3,4],
    "sex":["男","女","男"],
    "job":["Saler","CEO","Programer"]
})
display(df1,df2)
idnameage
01张三22
12李四33
23王五44
idsexjob
02Saler
13CEO
24Programer
# 默认时内连接 inner join
df1.merge(df2)
idnameagesexjob
02李四33Saler
13王五44CEO
df1.merge(df2,how="inner")
idnameagesexjob
02李四33Saler
13王五44CEO
  • 外合并 how=“outer”:补NaN
# 外连接,显示两个表的所有数据,没有的补NaN
df1.merge(df2,how="outer")
idnameagesexjob
01张三22.0NaNNaN
12李四33.0Saler
23王五44.0CEO
34NaNNaNProgramer
  • 左合并:how=“left”,右合并:how=“right”
# 左连接:显示左边表的所有数据和右边表的公共数据
df1.merge(df2,how="left")
idnameagesexjob
01张三22NaNNaN
12李四33Saler
23王五44CEO
# 右连接:显示右边表的所有数据和左边表公共数据
df1.merge(df2,how="right")
idnameagesexjob
02李四33.0Saler
13王五44.0CEO
24NaNNaNProgramer

6. 列冲突的解决

当列冲突时,即有多个列名称相同时,需要使用 on= 来指定哪一列作为key,配合suffixes指定冲突列名

可以使用 suffixes= 自己指定后缀

df1 = pd.DataFrame({
    "id":[1,2,3],
    "name":["张三","李四","王五"],
    "age":[22,33,44],
})
df2 = pd.DataFrame({
    "id":[2,3,4],
    "name":["男","女","男"],
    "job":["Saler","CEO","Programer"]
})
display(df1,df2)
idnameage
01张三22
12李四33
23王五44
idnamejob
02Saler
13CEO
24Programer
df1.merge(df2,on="id",suffixes=["_df1","_df2"])
idname_df1agename_df2job
02李四33Saler
13王五44CEO

7. merge合并总结

  • 合并有三种现象:一对一,多对一,多对多
  • 合并默认会找相同的列名进行合并,如果有多个列名相同,用on来指定
  • 如果没有列名相同,但是数据又相同,可以通过left_on,right_on来分别指定要合并的列
  • 如果想和index合并,使用left_index,right_index来指定
  • 如果多个列相同,合并之后可以通过suffixes来区分
  • 还可以通过how来控制合并的结果,默认时内合并,还有外合并outer,左合并left,右合并right

  • 21
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

腾飞开源

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值