Merge在之前的笔记中就已经介绍过了。它的用处可以看成是数据库操作中的join。即,将两个表,根据某个共同的key横向拼接成一个表。
先导入连个需要用到的包:
import pandas as pd
import numpy as np
1. 有相同列标签的情况下
然后通过dict创建两个DataFrame,分别都有两列,其中有一列的列标签相同;另一列分别是在0到10之间随机产生的均匀分布的整型数据。
df_obj1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
'data1' : np.random.randint(0,10,7)})
df_obj2 = pd.DataFrame({'key': ['a', 'b', 'd'],
'data2' : np.random.randint(0,10,3)})
print df_obj1
print df_obj2
data1 key
0 3 b
1 1 b
2 4 a
3 5 c
4 2 a
5 1 a
6 4 b
data2 key
0 8 a
1 2 b
2 7 d
不指定外键
现在要将以上两个DataFrame合并,以下直接调用.merge( ) ,并且传入这两个DataFrame。
默认情况下将重叠列的列名作为“外键”进行连接。这两个DataFrame有相同的列标签key,故合并的时候以它为外键。
print pd.merge(df_obj1, df_obj2)
data1 key data2
0 3 b 2
1 1 b 2
2 4 b 2
3 4 a 8
4 2 a 8
5 1 a 8
指定外键
对于有相同列标签的两个DataFrame,也可以认为地指定外键:on=“label”,结果与上面是一样滴。
# on显示指定“外键”
print pd.merge(df_obj1, df_obj2, on='key')
data1 key data2
0 3 b 2
1 1 b 2
2 4 b 2
3 4 a 8
4 2 a 8
5 1 a 8
2.列标签不同的情况下
在实际的需求中,两个DataFrame的列标签往往不同命名。
下面先将上面的两个DataFrame的key分别改成不同的名字:
# 更改列名
df_obj1 = df_obj1.rename(columns={'key':'key1'})
df_obj2 = df_obj2.rename(columns={'key':'key2'})
print df_obj1
print df_obj2
data1 key1
0 3 b
1 1 b
2 4 a
3 5 c
4 2 a
5 1 a
6 4 b
data2 key2
0 8 a
1 2 b
2 7 d
现在要将这两个DataFrame合并,就需要分别指定左右两个表中哪列来作为外键。
left_on,right_on分别指定左侧数据和右侧数据的“外键”
print pd.merge(df_obj1, df_obj2, left_on='key1', right_on='key2')
data1 key1 data2 key2
0 3 b 2 b
1 1 b 2 b
2 4 b 2 b
3 4 a 8 a
4 2 a 8 a
5 1 a 8 a
我们发现,上面的合并结果中,df_obj1中行索引为3的那一行不见了,因为key1中的c在df_obj2中没有,所有删除了,于是很明显,这是一个内链接 inner join.
于是我们也知道,在默认情况下,两个表的merge是进行内连接的操作。
.
于是,既然有内链接,那么肯定有外连接,左连接,右连接。选择什么类型的链接,只需要传入参数how=” “即可.
没有匹配上的位置,会直接用NaN补全。
于是,下面分别举了例子:
# “外连接”
print pd.merge(df_obj1, df_obj2, left_on='key1', right_on='key2', how='outer')
data1 key1 data2 key2
0 3.0 b 2.0 b
1 1.0 b 2.0 b
2 4.0 b 2.0 b
3 4.0 a 8.0 a
4 2.0 a 8.0 a
5 1.0 a 8.0 a
6 5.0 c NaN NaN
7 NaN NaN 7.0 d
# 左连接
print pd.merge(df_obj1, df_obj2, left_on='key1', right_on='key2', how='left')
data1 key1 data2 key2
0 3 b 2.0 b
1 1 b 2.0 b
2 4 a 8.0 a
3 5 c NaN NaN
4 2 a 8.0 a
5 1 a 8.0 a
6 4 b 2.0 b
# 右连接
print pd.merge(df_obj1, df_obj2, left_on='key1', right_on='key2', how='right')
data1 key1 data2 key2
0 3.0 b 2 b
1 1.0 b 2 b
2 4.0 b 2 b
3 4.0 a 8 a
4 2.0 a 8 a
5 1.0 a 8 a
6 NaN NaN 7 d
3. 处理重复列名
如果将两个DataFrame合并的时候会出现相同的列名,那么自然是要修改它们使其不同了。
可以直接在merge操作中传入参数suffixs=表示对左右两个表中除了键以外的列名都加上对应的后缀。
# 处理重复列名
df_obj1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
'data' : np.random.randint(0,10,7)})
df_obj2 = pd.DataFrame({'key': ['a', 'b', 'd'],
'data' : np.random.randint(0,10,3)})
print pd.merge(df_obj1, df_obj2, on='key', suffixes=('_left', '_right'))
data_left key data_right
0 6 b 9
1 5 b 9
2 5 b 9
3 9 a 1
4 6 a 1
5 1 a 1
4. 按索引连接
如下例子,df_obj2中的索引与df_obj1中的列”key”做merge。
只需添加参数right_index=True 表示右表使用索引为键。
# 按索引连接
df_obj1 = pd.DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
'data1' : np.random.randint(0,10,7)})
df_obj2 = pd.DataFrame({'data2' : np.random.randint(0,10,3)}, index=['a', 'b', 'd'])
print df_obj1
print df_obj2
data1 key
0 1 b
1 4 b
2 2 a
3 9 c
4 8 a
5 0 a
6 5 b
data2
a 8
b 6
d 9
print pd.merge(df_obj1, df_obj2, left_on='key', right_index=True)
data1 key data2
0 1 b 6
1 4 b 6
6 5 b 6
2 2 a 8
4 8 a 8
5 0 a 8
注:部分例子来自于小象学院Robin课程