Pandas 合并(merge)

本文深入讲解Pandas库中的merge函数,演示如何通过指定基准列、使用左连接、右连接、外连接等方式进行数据合并,同时介绍了如何处理多个键和索引的合并。

Pandas 合并(merge),对于合并操作,熟悉SQL的同学可以将其理解为JOIN操作,它使用一个或多个键把多行数据结合在一起。

原文参考 https://coolcou.com/pandas/pandas-data-process/pandas-merger-merge.html

跟关系数据库打交道的同学通常使用SQL的JOIN查询,用几个表共用的引用值(键)从不同的表获取数据。以这些键为基础,我们能够获取列表形式的新数据,这些数据是对几个表中的数据进行组合得到的。Pandas库中这类操作叫做合并,执行合并操作的函数为merge()

阅读本章内容前,可以先学习Pandas基础教程Pandas数据读写

使用merge()函数进行合并

如下所示,首先定义两个DataFrame对象,然后对两个DataFrame对象应用merge()函数进行合并操作。

import pandas as pd

frame1 = pd.DataFrame({'id':['ball', 'pencil', 'pen', 'mug', 'ashtray'],
                       'price':['12.33', '11.44', '33.21', '12.23', '33.62']})
frame2 = pd.DataFrame({'id':['pencil', 'pencil', 'ball', 'pen'],
                       'color':['white', 'red', 'red', 'black']})
print(frame1)
print('------------')
print(frame2)
print('-----------')
print(pd.merge(frame1, frame2))

输出结果如下:
在这里插入图片描述
如上所示,返回的DataFrame对象由原来两个DataFrame对象中ID相同的行组成,出了id这一列,新DataFrame包含了属于两个DataFrame的其他列。

on 选项指定基准列

在上面例子中,没有为merge()指定基于哪一列进行合并,实际应用中,常常需要指定基于哪一列进行合并。具体做法是增加on选项,把列的名称作为用于合并的键赋值给它。如下所示:

import pandas as pd

frame1 = pd.DataFrame({'id':['ball', 'pencil', 'pen', 'mug', 'ashtray'],
                       'color':['white', 'red', 'red', 'black','green'],
                       'brand':['OMG', 'ABC', 'ABC', 'POD', 'POD']})
frame2 = pd.DataFrame({'id':['pencil', 'pencil', 'ball', 'pen'],
                       'brand':['OMG', 'POD', 'ABC', 'POD']})
print(frame1)
print('------------')
print(frame2)
print('-----------')
print(pd.merge(frame1, frame2))

输出结果如下:
在这里插入图片描述

如上所示,由于我们定义的两个DataFrame对象,一个对象的列名称在另一个对象中也存在,所以对它们执行合并操作将得到一个空DataFrame对象。

因此我们需要明确定义pandas合并操作需要遵循的标准,我们用on选项指定合并操作所依据的基准列,合并标准不同,合并结果也会不同,如下所示:

import pandas as pd

frame1 = pd.DataFrame({'id':['ball', 'pencil', 'pen', 'mug', 'ashtray'],
                       'color':['white', 'red', 'red', 'black','green'],
                       'brand':['OMG', 'ABC', 'ABC', 'POD', 'POD']})
frame2 = pd.DataFrame({'id':['pencil', 'pencil', 'ball', 'pen'],
                       'brand':['OMG', 'POD', 'ABC', 'POD']})
print(pd.merge(frame1, frame2,on='id'))
print("------------")
print(pd.merge(frame1, frame2,on='brand'))

输出结果如下:
在这里插入图片描述

问题如影随形,假如两个DataFrame基准列的名称不一致,又该如何进行合并呢?为此,我们可以使用left_onright_on选项指定第一个和第二个DataFrame的基准列,如下所示:

import pandas as pd

frame1 = pd.DataFrame({'id':['ball', 'pencil', 'pen', 'mug', 'ashtray'],
                       'color':['white', 'red', 'red', 'black','green'],
                       'brand':['OMG', 'ABC', 'ABC', 'POD', 'POD']})
frame2 = pd.DataFrame({'id':['pencil', 'pencil', 'ball', 'pen'],
                       'brand':['OMG', 'POD', 'ABC', 'POD']})
frame2.columns = ['brand', 'sid']
print(frame1)
print('------------')
print(frame2)
print('------------')
print(pd.merge(frame1,frame2,left_on='id',right_on='sid'))

输出结果如下:
在这里插入图片描述

左连接,右连接,外连接

如上所示,merge()函数默认执行的是内连接操作,上述结果执行的是交叉操作,其他还支持左连接右连接外连接外连接把所有的键整合在一起,其效果相当于左连接右连接的效果之和,连接类型用how选项指定。如下所示:

import pandas as pd

frame1 = pd.DataFrame({'id':['ball', 'pencil', 'pen', 'mug', 'ashtray'],
                       'color':['white', 'red', 'red', 'black','green'],
                       'brand':['OMG', 'ABC', 'ABC', 'POD', 'POD']})
frame2 = pd.DataFrame({'id':['pencil', 'pencil', 'ball', 'pen'],
                       'brand':['OMG', 'POD', 'ABC', 'POD']})
frame2.columns = ['brand', 'id']
print(frame1)
print('------------')
print(frame2)
print('------------')
print(pd.merge(frame1,frame2,on='id'))

执行结果如下:
在这里插入图片描述
分别执行外连接左连接右连接,如下所示:

import pandas as pd

frame1 = pd.DataFrame({'id':['ball', 'pencil', 'pen', 'mug', 'ashtray'],
                       'color':['white', 'red', 'red', 'black','green'],
                       'brand':['OMG', 'ABC', 'ABC', 'POD', 'POD']})
frame2 = pd.DataFrame({'id':['pencil', 'pencil', 'ball', 'pen'],
                       'brand':['OMG', 'POD', 'ABC', 'POD']})
frame2.columns = ['brand', 'id']
print(pd.merge(frame1,frame2,how='outer'))
print('------------')
print(pd.merge(frame1,frame2,how='left'))
print('------------')
print(pd.merge(frame1,frame2,how='right'))

输出结果如下:

  brand  color       id
0   OMG  white     ball
1   ABC    red   pencil
2   ABC    red      pen
3   POD  black      mug
4   POD  green  ashtray
5   OMG    NaN   pencil
6   POD    NaN   pencil
7   ABC    NaN     ball
8   POD    NaN      pen
------------
  brand  color       id
0   OMG  white     ball
1   ABC    red   pencil
2   ABC    red      pen
3   POD  black      mug
4   POD  green  ashtray
------------
  brand color      id
0   OMG   NaN  pencil
1   POD   NaN  pencil
2   ABC   NaN    ball
3   POD   NaN     pen

要合并多个键,则把多个键赋值为on选项,如下示:

import pandas as pd

frame1 = pd.DataFrame({'id':['ball', 'pencil', 'pen', 'mug', 'ashtray'],
                       'color':['white', 'red', 'red', 'black','green'],
                       'brand':['OMG', 'ABC', 'ABC', 'POD', 'POD']})
frame2 = pd.DataFrame({'id':['pencil', 'pencil', 'ball', 'pen'],
                       'brand':['OMG', 'POD', 'ABC', 'POD']})
frame2.columns = ['brand', 'id']
print(pd.merge(frame1,frame2,on=['id','brand'],how='outer'))

输出结果如下:
在这里插入图片描述

根据索引进行合并

有的时候,合并操作不是用DataFrame的列,而是用索引作为键。把left_indexright_index选项的值置为True,就可将其作为合并DataFrame的基准。如下所示:

import pandas as pd

frame1 = pd.DataFrame({'id':['ball', 'pencil', 'pen', 'mug', 'ashtray'],
                       'color':['white', 'red', 'red', 'black','green'],
                       'brand':['OMG', 'ABC', 'ABC', 'POD', 'POD']})
frame2 = pd.DataFrame({'id':['pencil', 'pencil', 'ball', 'pen'],
                       'brand':['OMG', 'POD', 'ABC', 'POD']})
frame2.columns = ['brand', 'id']
print(pd.merge(frame1,frame2,right_index=True,left_index=True))

输出结果如下:
在这里插入图片描述

DataFrame对象的join()函数更适合于根据索引进行合并,我们可以用它合并多个索引相同列不同的DataFrame对象。如上所示,因为frame1的列名称和frame2的列名称有重合,直接调用frame1.join(frame2)会给出错误信息,这里要重命名frame2的列。如下所示:

import pandas as pd

frame1 = pd.DataFrame({'id':['ball', 'pencil', 'pen', 'mug', 'ashtray'],
                       'color':['white', 'red', 'red', 'black','green'],
                       'brand':['OMG', 'ABC', 'ABC', 'POD', 'POD']})
frame2 = pd.DataFrame({'id':['pencil', 'pencil', 'ball', 'pen'],
                       'brand':['OMG', 'POD', 'ABC', 'POD']})
frame2.columns = ['brand2', 'id2']
print(frame1.join(frame2))

输出结果如下:
在这里插入图片描述

如上所示,合并操作是以索引而不是列为基准,合并后得到的DataFrame对象包含了只存在于frame1的索引4,整合了frame2,索引为4的各元素使用NaN填充。

相关文章参考
Pandas 旋转数据
Pandas 删除数据
Pandas 拼接(concat)
Pandas GroupBy 用法

### 如何使用 `pandas.merge` 函数合并数据框 #### 基本语法 `pandas.merge()` 是用于将两个 DataFrame 对象基于一个或多个键进行连接的操作。此方法类似于 SQL 的 JOIN 操作,支持多种类型的连接方式。 ```python import pandas as pd df1 = pd.DataFrame({ 'key': ['A', 'B', 'C', 'D'], 'value_1': [1, 2, 3, 4] }) df2 = pd.DataFrame({ 'key': ['B', 'D', 'E', 'F'], 'value_2': [5, 6, 7, 8] }) ``` #### 单个键上的内连接 (Inner Join) 当仅有一个共同作为键时,可以执行如下操作来完成两者的内连接: ```python merged_df_inner = pd.merge(df1, df2, on='key') print(merged_df_inner) ``` 上述代码会返回只保留两个原始表格中共有的键值对应的行[^1]。 #### 多个键上的外连接 (Outer Join) 如果存在多于一个的匹配条件,则可以通过传递表给 `on` 参数来进行多键合并;而设置 `how='outer'` 可以获取所有记录,即使某些键在一个表中有而在另一个表中不存在也无妨: ```python merged_df_outer = pd.merge( df1, df2, how='outer', on=['key'] ) print(merged_df_outer) ``` 这里展示的是全外连接的结果,即包含了左表和右表所有的组合情况[^4]。 #### 左连接 (Left Join) 和 右连接 (Right Join) 对于只需要左侧或者右侧全部的数据加上另一侧相交部分的情况,可以选择做左连接或是右连接: - **左连接** ```python merged_df_left = pd.merge(df1, df2, how="left", on=["key"]) print(merged_df_left) ``` - **右连接** ```python merged_df_right = pd.merge(df1, df2, how="right", on=["key"]) print(merged_df_right) ``` 这两种情况下分别保持左边或右边完整的索引不变,并填充对方独有的项为 NaN[^2]。 #### 笛卡尔积连接 (Cartesian Product) 为了得到两张表之间每一对可能的配对关系——也就是所谓的笛卡尔乘积效果,可以在调用 `merge()` 方法时不指定任何公共键字段,而是利用交叉联结的方式实现这一点: ```python cartesian_product = pd.merge(df1.assign(dummy=1), df2.assign(dummy=1), on='dummy').drop('dummy', axis=1) print(cartesian_product) ``` 这段代码先向两个 DataFrame 添加了一个名为 "dummy" 的辅助并将它们设为相同的常数值,之后再依据这个新加入的临时键来做常规意义上的内部联合,最终删除掉不再需要的中间件 "dummy"[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值