引言
如果小伙伴使用过mysql,那么肯定知道mysql有join查询来连接多个表,这在数据处理中有时非常有用,对于强大的Pandas库来说,当然也有这种功能,而且Pandas也提供了将不同的DataFrame进行连接的操作,下面挨个介绍,并会加上实例
pd.merge() | pd.join()
merge和join方法都可以用于DF的合并,不过有些区别。
先看一下pd.merge()方法的参数
这里说一下他的参数,主要是比较常用的参数。
* left,right:表示想要进行合并的DataFrame
* how,值可以是inner,left,right,outer,使用过mysql的人应该知道这是什么意思吧?就不过多翻译了,默认值是inner
* left_on,right_on是用来指定希望用来作用合并依据的列名,如果不指定的话会自动寻找列名相同的列进行合并
* left_index,right_index设置为True的话表示使用该DF的列索引作为合并的根据进行合并
* sort默认为False,设置为True时表示合并时会根据给定的列值(也就是前面的left_on这种指定的列的值)来进行排序后再输出
* suffixes是用来给重名的列增加后缀名的,可以使用默认值也可以自己修改,比如要合并df1和df2都有一个列的名字是data,那么合并后left的DF的data列名变为了data_x
下面给个例子
df3:
data1 lkey
0 0 b
1 1 b
2 2 a
3 3 c
4 4 a
5 5 b
df4:
data2 rkey
0 3 a
1 1 b
2 2 a
3 3 b
4 4 d
执行以下命令
pd.merge(df3,df4,how='inner',left_on='lkey',right_on='rkey',sort=True)
输出为:
data1 lkey data2 rkey
0 2 a 3 a
1 2 a 2 a
2 4 a 3 a
3 4 a 2 a
4 0 b 1 b
5 0 b 3 b
6 1 b 1 b
7 1 b 3 b
8 5 b 1 b
9 5 b 3 b
分析一下参数,首先传入的是需要进行合并的DF,方式是inner,当然可以进行left,right等,使用
inner会生成df3,df4共同拥有的key值进行合并,此时df3的lkey为a的行共有两行,df4的rkey的为
a的行共有2行,生成的结果是a的笛卡尔积一共是2*2=4行。sort为True,可以看到lkey和rkey都是
按照值进行排序输出的
下面使用
pd.merge(df3,df4,how='left',left_index=True,right_index=True,sort=True)
输出为:
data1 lkey data2 rkey
0 0 b 3.0 a
1 1 b 1.0 b
2 2 a 2.0 a
3 3 c 3.0 b
4 4 a 4.0 d
5 5 b NaN NaN
这里参数的变化是使用索引号作为合并的根据,这里使用了左右两个DF的索引
连接的方式变为了左连接(df3的索引为0-5,df4的索引为0-4,所以合并后最后一行后面俩个元素为NaN)
这里说明一下,可以用pd.merge(df1,df2)的顶级方法,也可以使用属性方法df1.merge(df2),参数都是相同的
如果想要根据索引进行合并的话还有个更方便的方法,就是DF.join()(不是顶级方法,注意调用方式)
df3.join(df4,how='left',sort=True) 这个语句的输出结果也是
data1 lkey data2 rkey
0 0 b 3.0 a
1 1 b 1.0 b
2 2 a 2.0 a
3 3 c 3.0 b
4 4 a 4.0 d
5 5 b NaN NaN
轴连接pd.concat()
该方法只有顶级方法,没有属性方法,所以不能通过df.concat()进行调用,注意!!!
还是先看一下参数,主要常用的参数有如下:
* objs:用来保存需要用来进行连接的Series/DataFrame,可以是列表或者dict类型
* axis表示希望进行连接的轴向,默认我0,也就是纵向拼接
* join有多个选择,inner,outer,这里默认值是outer,下面会根据实例来比较下
* join_axes默认为空,可以设置值指定为其他轴上使用的索引
* ignore_index,连接后原来两个DF的index值会被保存,如果该索引没有实际的意义可以设置为True来进行重分配index号
下面看下实例
df3:
data1 lkey
0 0 b
1 1 b
2 2 a
3 3 c
4 4 a
5 5 b
df4:
data2 rkey
0 3 a
1 1 b
2 2 a
3 3 b
4 4 d
pd.concat([df3,df4],axis=0,join='outer')
输出为:
data1 data2 lkey rkey
0 0.0 NaN b NaN
1 1.0 NaN b NaN
2 2.0 NaN a NaN
3 3.0 NaN c NaN
4 4.0 NaN a NaN
5 5.0 NaN b NaN
0 NaN 3.0 NaN a
1 NaN 1.0 NaN b
2 NaN 2.0 NaN a
3 NaN 3.0 NaN b
4 NaN 4.0 NaN d
将df3,df4组成列表传入,按0轴进行连接,join方式是outer,也就是两个df的列进行了outer操作,发现两个df等于是从上到下叠加了,只不过本来各自二维特征都变成了四维特征
pd.concat([df3,df4],axis=1,join='outer')
输出为:
data1 lkey data2 rkey
0 0 b 3.0 a
1 1 b 1.0 b
2 2 a 2.0 a
3 3 c 3.0 b
4 4 a 4.0 d
5 5 b NaN NaN
按照1轴进行连接,发现索引是df3和df4中outer结果后的索引,这里可以想到,如果使用inner,那是不是应该是df3和df4的交集的笛卡尔积呢?下面看一下
pd.concat([df3,df4],axis=1,join='inner')
输出为:
data1 lkey data2 rkey
0 0 b 3 a
1 1 b 1 b
2 2 a 2 a
3 3 c 3 b
4 4 a 4 d
可以看到只输出了索引为0-4的行,和前面的推测相等
pd.concat()可以将多个列表进行连接,也就是列表里包含多个DataFrame
join_axes的作用:用来表示使用的索引的值,值是list of Index objects,替换另一维的索引
pd.concat([df3,df4],axis=1,join_axes=[pd.Series([1,2,3,10])])
这里使用axis=0,所以替换的是index,如果axis=1,那么替换的就是columns
结果是:
data1 lkey data2 rkey
1 1.0 b 1.0 b
2 2.0 a 2.0 a
3 3.0 c 3.0 b
10 NaN NaN NaN NaN
输出的索引被我们刚刚设置为了1,2,3,4,只有对应索引的值可以获得输出,而索引为10的行并没有数值,所以为NaN
还记得之前直接进行连接索引的顺序是0,1,2,3,4,5,0,1,2,3,4么,也许你希望得到一个顺序的索引那么就要用过ignore_index了
pd.concat([df3,df4],ignore_index=True)
data1 data2 lkey rkey
0 0.0 NaN b NaN
1 1.0 NaN b NaN
2 2.0 NaN a NaN
3 3.0 NaN c NaN
4 4.0 NaN a NaN
5 5.0 NaN b NaN
6 NaN 3.0 NaN a
7 NaN 1.0 NaN b
8 NaN 2.0 NaN a
9 NaN 3.0 NaN b
10 NaN 4.0 NaN d
索引就是重新排的了