前言:
Pandas 的基本特性之一就是高性能的内存式数据连接(join)与合并(merge)操作。pdrge() 函数实现了三种数据连接的类型:一对一、多对一和多对多。这三种数据连接 类型都通过 pdrge() 接口进行调用,根据不同的数据连接需求进行不同的操作。
一、数据连接的类型
1.一对一连接
一对一连接是最简单的数据合并类型。
df1= pd.DataFrame({'员工': ['Bob', 'Jake', 'Lisa', 'Sue'], '组': ['Accounting', 'Engineering', 'Engineering', 'HR']})df2= pd.DataFrame({'员工': ['Lisa', 'Bob', 'Jake', 'Sue'], '入职': [2004, 2008, 2012, 2014]})
上次讲解了怎么用concat函数合并成一个DataFrame,下面使用pdrge函数实现。
df3= pdrge(df1, df2)df3
代码结果:
pdrge() 方发现两个 DataFrame 都有“员工”这一列,并会自动以这列作为键进行连接。两个输入的合并结果是一个新的 DataFrame。需要注意的是共同列的位置可以是不一致的。
2. 多对一连接
多对一连接是指,在需要连接的两个列中,有一列的值有重复。通过多对一连接获得的结果 DataFrame 将会保留重复值。
df4= pd.DataFrame({'组': ['Accounting', 'Engineering', 'HR'], '管理组': ['Carly', 'Guido', 'Steve']})pdrge(df1,df4)
代码结果:
在结果 DataFrame 中多了一个“管理组”列,里面有些值会因为输入数据的对应关系而有所重复。
3. 多对多连接
多对多连接是个有点儿复杂的概念,如果左右两个输入的共同列都包含重复值,那么合并的结果就是一种多对多连接。
df5= pd.DataFrame({'组': ['Accounting', 'Accounting', 'Engineering', 'Engineering', 'HR', 'HR'], '技能': ['math', 'spreadsheets', 'coding', 'linux', 'spreadsheets', 'organization']})pdrge(df1, df5)
代码结果:
这三种数据连接类型可以直接与其他 Pandas 工具组合使用,从而实现各种各样的功能。但是工作中的真实数据集往往并不像示例中演示的那么干净、整洁。
二、设置数据合并的键
1.参数on的用法
最简单的方法就是直接将参数 on 设置为一个列名字符串或者一个包含多列名称的列表。
pdrge(df1, df2, on='员工')
代码结果:
这个参数只能在两个 DataFrame 有共同列名的时候才可以使用。
2.left_on与right_on参数
有时候要合并两个列名不同的数据集,就可以用 left_on 和 right_on 参数来指定列名。
df7= pd.DataFrame({'名字': ['Bob', 'Jake', 'Lisa', 'Sue'], '薪水': [70000, 80000, 120000, 90000]})pdrge(df1, df7, left_on=\"员工\", right_on=\"名字\")
代码结果:
获取的结果中会有一个多余的列,可以通过 DataFrame 的 drop() 方法将这列去掉。
pdrge(df1, df3, left_on=\"员工\", right_on=\"名字\").drop('名字', axis=1)组
代码结果:
3.left_index与right_index参数
除了合并列之外,你可能还需要合并索引。
df1a= df1.set_index('员工')df2a= df2.set_index('员工')print(df1a)print(df2a)
代码结果:
员工 组 Bob AccountingJake EngineeringLisa EngineeringSue HR 员工 入职 Lisa 2004Bob 2008Jake 2012Sue 2014
以通过设置 pdrge() 中的 left_index 和 / 或 right_index 参数将索引设置为键来实现合并。
pdrge(df1a, df2a, left_index=True, right_index=True,)
代码结果:
4.用 join() 方法:按照索引进行数据合并
df1a.join(df2a)
代码结果:
如果想将索引与列混合使用,那么可以通过结合 left_index 与 right_on,或者结合 left_ on 与 right_index 来实现
pdrge(df1a, df3, left_index=True, right_on='名字')
代码结果:
三、设置数据连接的集合操作规则
集合操作规则:当一个值出现在一列,却没有出现在另一列时,就需要考虑集合操作规则了。
df8= pd.DataFrame({'名字': ['Peter', 'Paul', 'Mary'], '食物': ['fish', 'beans', 'bread']}, columns=['名字', '食物'])df9= pd.DataFrame({'名字': ['Mary', 'Joseph'], '酒': ['wine', 'beer']}, columns=['名字', '酒'])pdrge(df8, df9)
代码结果:
在合并这两个数据集时,在“名字”列中只有一个共同的值,结果中只会包含两个集合的交集。
1.外连接(outer join):返回两个输入列的交集,所有缺失值都用 NaN 填充。
pdrge(df8, df9, how='outer')
代码结果:
2.左连接(left join)和右连接(right join):返回的结果分别只包含左列和右列。
pdrge(df8, df9, how='right')
代码结果:
现在输出的行中只包含右边输入列的值。
pdrge(df8, df9, how='left')
代码结果:
现在输出的行中只包含左边输入列的值。
3.重复列名:suffixes参数
你有时候可能会遇到两个输入 DataFrame 有重名列的情况。
df8a= pd.DataFrame({'名字': ['Bob', 'Jake', 'Lisa', 'Sue'], '排名': [1, 2, 3, 4]})df9b= pd.DataFrame({'名字': ['Bob', 'Jake', 'Lisa', 'Sue'], '排名': [3, 1, 4, 2]})pdrge(df8a, df9b, on=\"名字\")
代码结果:
由于输出结果中有两个重复的列名,因此 pdrge() 函数会自动为它们增加后缀 _x 或 _y, 当然也可以通过 suffixes 参数自定义后缀名。
pdrge(df8a, df9b, on=\"名字\", suffixes=[\"_L\", \"_R\"])
代码结果:
suffixes 参数同样适用于任何连接方式,即使有三个及三个以上的重复列名时也同样适用。