一、关系连接
-
键连接
在
pandas
中的关系型连接函数merge
和join
中提供了how
参数来代表连接形式,分为左连接left
、右连接right
、内连接inner
、外连接outer
。现有如下两个表格,下面基于这两个表格展示左右连接,内外连接的形式。df1 = pd.DataFrame({'Name':['San Zhang','Si Li'], 'Age':[20,30]}) df2 = pd.DataFrame({'Name':['Si Li','Wu Wang'], 'Gender':['F','M']})
Name Age 0 张三 20 1 李四 30 Name Gender 0 张三 F 1 王五 M -
左连接
基于左边的键进行连接,如果右表的键在左表中,则添加到左表中,如下所示:
df1.merge(df2, on='Name', how='left')
Name Age Gender 0 张三 NaN 1 李四 F -
右连接
和左连接类似,不过基于的是右表,结果如下:
df1.merge(df2, on='Name', how='right')
Name Age Gender 0 Si Li 30 F 1 Wu Wang nan M -
内连接
合并左右都出现的键,结果如下:
df1.merge(df2, on='Name', how='inner')
Name Age Gender 0 Si Li 30 F -
外连接
左右表中出现的键都会合并,结果如下:
df1.merge(df2, on='Name', how='outer')
Name Age Gender 0 San Zhang 20 nan 1 Si Li 30 F 2 Wu Wang nan M -
注意:
若同一个表中的键出现重复,只要两边同时出现的值,就以笛卡尔积的方式加入。
-
-
值连接
-
连接具有不同名称的列:
left_on
和right_on
确定df1 = pd.DataFrame({'df1_name':['San Zhang','Si Li'], 'Age':[20,30]}) df2 = pd.DataFrame({'df2_name':['Si Li','Wu Wang'], 'Gender':['F','M']}) df1.merge(df2, left_on='df1_name', right_on='df2_name', how='left')
df1_name Age df2_name Gender 0 San Zhang 20 nan nan 1 Si Li 30 Si Li F -
连接重复的列名:
suffixes
参数指定Name Grade_Chinese Grade_Math 0 San Zhang 70 80 -
连接重复的元素:
on
参数指定成多列,确保结果唯一df1 = pd.DataFrame({'Name':['San Zhang', 'San Zhang'], 'Age':[20, 21], 'Class':['one', 'two']}) df2 = pd.DataFrame({'Name':['San Zhang', 'San Zhang'], 'Gender':['F', 'M'], 'Class':['two', 'one']}) df1.merge(df2, on=['Name', 'Class'], how='left')
Name Age Class Gender 0 San Zhang 20 one M 1 San Zhang 21 two F
-
-
索引连接
把索引作为键,使用
join
函数处理。以第2小节最后一个为例,此时对于
merge
是要对on
传入多列,使用join
函数时,需要将索引变为多级索引:df1 = pd.DataFrame({'Age':[20,21]}, index=pd.MultiIndex.from_arrays( [['San Zhang', 'San Zhang'],['one', 'two']], names=('Name','Class'))) df2 = pd.DataFrame({'Gender':['F', 'M']}, index=pd.MultiIndex.from_arrays( [['San Zhang', 'San Zhang'],['two', 'one']], names=('Name','Class'))) df1.join(df2)
Name Age Class Gender 0 San Zhang 20 one M 1 San Zhang 21 two F
二、方向连接
-
contact
- axis:拼接方向,默认为0,表示纵向拼接,为1表示横向拼接
- join:连接形式,默认为outer,纵向拼接时,表示保留所有列,不存在的值设为确失,
inner
表示保留共同列;横向则为行。 - keys:表示新表中的元素来自哪一个旧表中
对于如下两个表:
df1 = pd.DataFrame({'Name':['San Zhang','Si Li'], 'Age':[20,30]})
Name Age 0 San Zhang 20 1 Si Li 30 df2 = pd.DataFrame({'Grade':[80, 90]}, index=[1, 2])
Grade 1 80 2 90 横向拼接,
join``设为
inner,则保留共同的行:pd.concat([df1, df2], axis=1, join='inner')
Name Age Grade 1 Si Li 30 80 横向拼接,默认保留所有行:
pd.concat([df1, df2], axis=1)
Name Age Grade 0 San Zhang 20 nan 1 Si Li 30 80 2 nan nan 90 keys
参数设['one'.'two']:pd.concat([df1, df2], axis=1,keys=['one'.'two'])
('one', 'Name') ('one', 'Age') ('two', 'Grade') 0 San Zhang 20 nan 1 Si Li 30 80 2 nan nan 90 -
序列与表合并
将一个表和序列进行合并:
- append:加入到表的行末,原表为整数索引时,可以使用
ignore_index=True
对新序列对应的索引自动标号,否则必须对Series
指定name
属性。 - assign:加入到表的列末,返回为临时副本,必须重新赋值。
- append:加入到表的行末,原表为整数索引时,可以使用
三、类连接
-
比较
比较两个表的不同值,通过
compare
函数实现,返回不同值所在的行和列,相同部分填充为nan。keep_shape = True
则保持表的形状:df1 = pd.DataFrame({'Name':['San Zhang', 'Si Li', 'Wu Wang'], 'Age':[20, 21 ,21], 'Class':['one', 'two', 'three']}) df2 = pd.DataFrame({'Name':['San Zhang', 'Li Si', 'Wu Wang'], 'Age':[20, 21 ,21], 'Class':['one', 'two', 'Three']}) df1.compare(df2, keep_shape=True)
('Name', 'self') ('Name', 'other') ('Age', 'self') ('Age', 'other') ('Class', 'self') ('Class', 'other') 0 nan nan nan nan nan nan 1 Si Li Li Si nan nan nan nan 2 nan nan nan nan three Three -
组合
combine:传入两个表,并按一定规则组合。规则通过传入函数确定,传入的列是两个表列名的并集。
def choose_min(s1, s2): s2 = s2.reindex_like(s1) res = s1.where(s1<s2, s2) res = res.mask(s1.isna()) # isna表示是否为缺失值,返回布尔序列 return res df1 = pd.DataFrame({'A':[1,2], 'B':[3,4], 'C':[5,6]}) df2 = pd.DataFrame({'B':[5,6], 'C':[7,8], 'D':[9,10]}, index=[1,2]) df1.combine(df2, choose_min)
A B C D 0 nan nan nan nan 1 nan 4 6 nan 2 nan nan nan nan 设置
overtwrite
参数为False
可以保留 被调用表 中未出现在传入的参数表中的列。df1.combine(df2, choose_min, overwrite=False)
A B C D 0 1 nan nan nan 1 2 4 6 nan 2 nan nan nan nan