pandas作为数据分析的利器,提供了数据读取,数据清洗,数据整形等一系列功能。当需要对多个数据集合并处理时,我们就需要对多个数据框进行连接操作,在pandas中,提供了以下多种实现方式
1. concat
concat函数可以在行和列两个水平上灵活的合并多个数据框,基本用法如下
>>> import numpy as np>>> import pandas as pd
>>> a = pd.DataFrame(np.random.randn(2,2),columns=['A','B'])
>>> a
A B
0 -1.809098 -0.405398
1 0.375546 -1.382664
>>> b = pd.DataFrame(np.random.randn(3,3),columns=['A','B', 'C'])
>>> b
A B C
0 -0.829604 1.090541 0.749220
1 -0.889822 2.227603 -1.211428
2 -1.824889 -0.687067 0.012370
>>> pd.concat([a, b])
A B C
0 -1.809098 -0.405398 NaN
1 0.375546 -1.382664 NaN
0 -0.829604 1.090541 0.749220
1 -0.889822 2.227603 -1.211428
2 -1.824889 -0.687067 0.012370
默认情况下,以行的方式合并多个数据框,对于子数据框中没有的列,以NaN进行填充。
concat函数有多个参数,通过修改参数的值,可以实现灵活的数据框合并。首先是axis参数,从numpy延伸而来的一个概念。对于一个二维的数据框而言,行为0轴, 列为1轴。该参数的默认值为0, 以行的方式进行合并,当设置为1时,表示以列的方式进行合并,示例如下
>>> pd.concat([a, b], axis = 0)A B C
0 -1.809098 -0.405398 NaN
1 0.375546 -1.382664 NaN
0 -0.829604 1.090541 0.749220
1 -0.889822 2.227603 -1.211428
2 -1.824889 -0.687067 0.012370
>>> pd.concat([a, b], axis = 1)
A B A B C
0 -1.809098 -0.405398 -0.829604 1.090541 0.749220
1 0.375546 -1.382664 -0.889822 2.227603 -1.211428
2 NaN NaN -1.824889 -0.687067 0.012370
观察上述的结果可以发现,合并数据框时,对于不同shape的数据框,尽管行标签和列标签有重复值,但是都是当做独立元素来处理,直接取了并集,这个行为实际上由join参数控制,默认值为outer。合并数据框时,沿着axis参数指定的轴进行合并,而join参数则控制在另外一个轴上,标签如何处理,默认的outer表示取并集,取值为inner时,取交集,只保留overlap的标签,示例如下
>>> pd.concat([a, b], join = "outer")A B C
0 -1.809098 -0.405398 NaN
1 0.375546 -1.382664 NaN
0 -0.829604 1.090541 0.749220
1 -0.889822 2.227603 -1.211428
2 -1.824889 -0.687067 0.012370
>>> pd.concat([a, b], join = "inner")
A B
0 -1.809098 -0.405398
1 0.375546 -1.382664
0 -0.829604 1.090541
1 -0.889822 2.227603
2 -1.824889 -0.687067
ignore_index参数表示忽略在axis参数指定的轴上的原有标签,默认值为False, 保留原有的标签,示例如下
# 保留原有的行标签>>> pd.concat([a, b], ignore_index = False)
A B C
0 -1.809098 -0.405398 NaN
1 0.375546 -1.382664 NaN
0 -0.829604 1.090541 0.749220
1 -0.889822 2.227603 -1.211428
2 -1.824889 -0.687067 0.012370
# 用从0开始的数字作为新的行标签
>>> pd.concat([a, b], ignore_index = True)
A B C
0 -1.809098 -0.405398 NaN
1 0.375546 -1.382664 NaN
2 -0.829604 1.090541 0.749220
3 -0.889822 2.227603 -1.211428
4 -1.824889 -0.687067 0.012370
keys参数指定指定一个新的index, 用来区分不同的子数据框,示例如下
>>> pd.concat([a, b], keys = ['a', 'b'])A B C
a 0 -1.809098 -0.405398 NaN
1 0.375546 -1.382664 NaN
b 0 -0.829604 1.090541 0.749220
1 -0.889822 2.227603 -1.211428
2 -1.824889 -0.687067 0.012370
names参数为index设置名称, 示例如下
>>> pd.concat([a, b], keys = ['a', 'b'], names = ['groupA', 'groupB'])A B C
groupA groupB
a 0 -1.809098 -0.405398 NaN
1 0.375546 -1.382664 NaN
b 0 -0.829604 1.090541 0.749220
1 -0.889822 2.227603 -1.211428
2 -1.824889 -0.687067 0.012370
verify_integrity参数默认值为False, 允许axis参数指定的轴上有重复的标签,当指定为False时,如果存在重复的标签,则会报错,示例如下
>>> pd.concat([a, b], verify_integrity=False))A B C
0 -1.809098 -0.405398 NaN
1 0.375546 -1.382664 NaN
0 -0.829604 1.090541 0.749220
1 -0.889822 2.227603 -1.211428
2 -1.824889 -0.687067 0.012370
>>> pd.concat([a, b], verify_integrity=True)
...
ValueError: Indexes have overlapping values: Int64Index([0, 1], dtype='int64')
2. merge
merge以SQL数据库类似的合并逻辑,来合并两个数据框。在SQL数据库中,每个数据表有一个主键,称之为key, 通过比较主键的内容,将两个数据表进行连接,基本用法如下
>>> a = pd.DataFrame({'name':['Rose', 'Andy', 'July'],'age':[21,22,18]})>>> a
name age
0 Rose 21
1 Andy 22
2 July 18
>>> b = pd.DataFrame({'name':['Rose', 'Andy', 'Jack'],'height':[172,168,175],'weight':[45,55,75]})
>>> b
name height weight
0 Rose 172 45
1 Andy 168 55
2 Jack 175 75
>>>
>>> a.merge(b)
name age height weight
0 Rose 21 172 45
1 Andy 22 168 55
默认情况下,会寻找标签名字相同的列作为key, 然后比较两个数据框中key列对应的元素,取交集的元素作为合并的对象。
通过on参数,可以显示的指定作为key的标签名称,注意用on参数指定的标签名称,必须在两个数据框中同时存在才行,用法如下
>>> a.merge(b, on='name')name age height weight
0 Rose 21 172 45
1 Andy 22 168 55
对key列元素取交集的行为则由how参数控制,默认值为inner, 表示取交集,共有4种取值,用法如下
# 默认值,取key对应的交集>>> a.merge(b, how='inner')
name age height weight
0 Rose 21 172 45
1 Andy 22 168 55
# outer表示取key的并集
# 没有的元素用NaN填充
>>> a.merge(b, how='outer')
name age height weight
0 Rose 21.0 172.0 45.0
1 Andy 22.0 168.0 55.0
2 July 18.0 NaN NaN
3 Jack NaN 175.0 75.0
# left表示只取第一个数据框中的key元素
>>> a.merge(b, how='left')
name age height weight
0 Rose 21 172.0 45.0
1 Andy 22 168.0 55.0
2 July 18 NaN NaN
# right表示,只取第二个数据框中的key元素
>>> a.merge(b, how='right')
name age height weight
0 Rose 21.0 172 45
1 Andy 22.0 168 55
2 Jack NaN 175 75
当两个数据框中没有overlap的标签名时,用on参数指定key就不行了,此时可以用left_on和right_on分别指定两个数据框中的key列,用法如下
>>> a = pd.DataFrame({'student_name':['Rose', 'Andy', 'July'],'age':[21,22,18]})>>> a
student_name age
0 Rose 21
1 Andy 22
2 July 18
>>> b = pd.DataFrame({'name':['Rose', 'Andy', 'Jack'],'height':[172,168,175],'weight':[45,55,75]})
>>> b
name height weight
0 Rose 172 45
1 Andy 168 55
2 Jack 175 75
>>> a.merge(b, left_on='student_name', right_on='name')
student_name age name height weight
0 Rose 21 Rose 172 45
1 Andy 22 Andy 168 55
当两个数据框除了key之外,还有相同的标签,默认会添加_x, _y后缀加以区分,通过suffixes参数可以自定义后缀,用法如下
>>> a.merge(b, on = 'name')name age height_x height_y weight
0 Rose 21 172 172 45
1 Andy 22 168 168 55
>>> a.merge(b, on = 'name', suffixes = ['_a', '_b'])
name age height_a height_b weight
0 Rose 21 172 172 45
1 Andy 22 168 168 55
默认都是将列标签作为key,通过指定left_index和right_index的值,可以将行标签作为key,用法如下
>>> a = pd.DataFrame({'name':['Rose', 'Andy', 'July'],'age':[21,22,18], 'height':[172,168,175]})>>> a
name age height
0 Rose 21 172
1 Andy 22 168
2 July 18 175
>>> b = pd.DataFrame({'name':['Rose', 'Andy', 'Jack'],'height':[172,168,175],'weight':[45,55,75]})
>>> b
name height weight
0 Rose 172 45
1 Andy 168 55
2 Jack 175 75
>>> a.merge(b, left_index = True, right_index = True)
name_x age height_x name_y height_y weight
0 Rose 21 172 Rose 172 45
1 Andy 22 168 Andy 168 55
2 July 18 175 Jack 175 75
3. join
join的合并方式和merge相同, 默认根据行标签进行合并, 优势在于可以一次处理多个数据框,用法如下
>>> a = pd.DataFrame(np.random.randn(2,2),columns=['A','B'])>>> a
A B
0 0.639820 1.680362
1 0.212621 1.204541
>>> b = pd.DataFrame(np.random.randn(3,3),columns=['A','B','C'])
>>> b
A B C
0 0.141238 -1.138415 0.769548
1 1.036439 -1.267921 -0.665270
2 -1.061909 -0.135067 -0.710007
>>> a.join(b, lsuffix='_a', rsuffix='_b')
A_a B_a A_b B_b C
0 0.639820 1.680362 0.141238 -1.138415 0.769548
1 0.212621 1.204541 1.036439 -1.267921 -0.665270
当两个数据框存在相同的列标签时,需要指定lsuffix和rsuffix参数,为相同的列标签加后缀进行区分。同样的,也有how参数控制合并的行为,在join函数中,how参数的默认值为left, 示例如下
>>> a.join(b, lsuffix='_a', rsuffix='_b')A_a B_a A_b B_b C
0 0.639820 1.680362 0.141238 -1.138415 0.769548
1 0.212621 1.204541 1.036439 -1.267921 -0.665270
# 默认值为left, 以第一个数据框的行作为输出行
>>> a.join(b, lsuffix='_a', rsuffix='_b',how='left')
A_a B_a A_b B_b C
0 0.639820 1.680362 0.141238 -1.138415 0.769548
1 0.212621 1.204541 1.036439 -1.267921 -0.665270
# right, 表示以第二个数据框的行作为输出行
>>> a.join(b, lsuffix='_a', rsuffix='_b',how='right')
A_a B_a A_b B_b C
0 0.639820 1.680362 0.141238 -1.138415 0.769548
1 0.212621 1.204541 1.036439 -1.267921 -0.665270
2 NaN NaN -1.061909 -0.135067 -0.710007
# inner,表示以二者的交集作为输出行
>>> a.join(b, lsuffix='_a', rsuffix='_b',how='inner')
A_a B_a A_b B_b C
0 0.639820 1.680362 0.141238 -1.138415 0.769548
1 0.212621 1.204541 1.036439 -1.267921 -0.665270
# outer, 表示以二者的并集作为输出行
>>> a.join(b, lsuffix='_a', rsuffix='_b',how='outer')
A_a B_a A_b B_b C
0 0.639820 1.680362 0.141238 -1.138415 0.769548
1 0.212621 1.204541 1.036439 -1.267921 -0.665270
2 NaN NaN -1.061909 -0.135067 -0.710007
4. append
append将两个数据框以行的方式进行合并,要求列数相同,用法如下
# append 函数,将新的数据框追加为行>>> a = pd.DataFrame(np.random.rand(2, 2), columns=['A', 'B'])
>>> b = pd.DataFrame(np.random.rand(2, 2), columns=['A', 'B'])
>>> a
A B
0 0.529614 0.712904
1 0.969706 0.943299
>>> b
A B
0 0.626073 0.293426
1 0.952565 0.251707
>>> a.append(b)
A B
0 0.529614 0.712904
1 0.969706 0.943299
0 0.626073 0.293426
1 0.952565 0.251707
5. assign
assign用于给数据框新增列,用法如下
# assign 函数,为数据框新增列>>> a.assign(C=pd.Series([1,2]))
A B C
0 0.529614 0.712904 1
1 0.969706 0.943299 2
# 多列就是多个关键词参数
>>> a.assign(C=pd.Series([1,2]),D=[1,2])
A B C D
0 0.529614 0.712904 1 1
1 0.969706 0.943299 2 2
concat, join,merge这3种方式可以合并不同shape的数据框,更加灵活强大,append和assign函数更具针对性。
·end·
一个只分享干货的
生信公众号