python--pandas合并与连接
合并与连接操作是数据处理中常见的,在pandas中用concat或append方法实现数据框的合并操作,
用merge或join方法实现数据框的连接操作。
环境
- python3.9
- win10 64bit
- pandas==1.2.1
append
append
方法根据行在原数据框添加新的数据框。
import pandas as pd
pd.set_option('display.notebook_repr_html',False)
# 数据准备
df = pd.DataFrame([[1, 2], [3, 4]], columns=list('AB'))
df2 = pd.DataFrame([[5, 6], [7, 8]], columns=list('AB'))
df
A B
0 1 2
1 3 4
df2
A B
0 5 6
1 7 8
# 行末添加新数据框
df.append(df2)
A B
0 1 2
1 3 4
0 5 6
1 7 8
如果想要合并后的数据框索引重写排序,可以设置参数ignore_index=True
。
# 行末添加新数据框(索引重新排序)
df.append(df2,ignore_index=True)
A B
0 1 2
1 3 4
2 5 6
3 7 8
concat
concat
函数是panda自带的,可以按行或按列合并多个pandas数据框。
# 数据准备
df1 = pd.DataFrame([['a', 1], ['b', 2]],columns=['letter', 'number'])
df2 = pd.DataFrame([['c', 3], ['d', 4]],columns=['letter', 'number'])
df3 = pd.DataFrame([['c', 3, 'cat'], ['d', 4, 'dog']],columns=['letter', 'number', 'animal'])
df1
letter number
0 a 1
1 b 2
df2
letter number
0 c 3
1 d 4
df3
letter number animal
0 c 3 cat
1 d 4 dog
按行合并多个数据框,需要注意的是objs参数接受一个可迭代对象。concat函数默认按行合并。
# 按行合并
pd.concat(objs=[df1,df2])
letter number
0 a 1
1 b 2
0 c 3
1 d 4
设置ignore_index=True
,使合并后的数据框索引重新排序。
# 按行合并(索引重排序)
pd.concat([df1,df2],ignore_index=True)
letter number
0 a 1
1 b 2
2 c 3
3 d 4
按行合并时,concat对所有的列进行全连接(参数join='outer'
),没有的列会填充为NaN。
pd.concat([df1,df3])
letter number animal
0 a 1 NaN
1 b 2 NaN
0 c 3 cat
1 d 4 dog
设置参数join='inner'
,可以只保留共有的列。
pd.concat([df1,df3],join='inner')
letter number
0 a 1
1 b 2
0 c 3
1 d 4
设置参数axis=1
或axis='columns'
,可以按列合并多个数据框。
# 按列合并数据框
pd.concat([df1,df2],axis=1)
letter number letter number
0 a 1 c 3
1 b 2 d 4
merge
merge
方法根据列或索引连接数据框。
# 数据准备
df1 = pd.DataFrame({'key': ['a', 'b', 'c'],
'value1': [1, 2, 3]})
df2 = pd.DataFrame({'key': ['b', 'c', 'd'],
'value2': [5, 6, 7]})
df1
key value1
0 a 1
1 b 2
2 c 3
df2
key value2
0 b 5
1 c 6
2 d 7
当两个数据框只有一个相同列时,merge
方法会自动根据相同列进行内连接,on
参数可以省略。
# 内连接,默认相同列连接
df1.merge(df2)
key value1 value2
0 b 2 5
1 c 3 6
# 内连接,指定列连接
df1.merge(df2,on='key')
key value1 value2
0 b 2 5
1 c 3 6
设置参数how=['left','right','outer','inner','cross']
,可以完成不同类型的连接。
# 外连接
df1.merge(df2,how='outer')
key value1 value2
0 a 1.0 NaN
1 b 2.0 5.0
2 c 3.0 6.0
3 d NaN 7.0
# 左连接
df1.merge(df2,how='left')
key value1 value2
0 a 1 NaN
1 b 2 5.0
2 c 3 6.0
# 右连接
df1.merge(df2,how='right')
key value1 value2
0 b 2.0 5
1 c 3.0 6
2 d NaN 7
# 交叉连接
df1.merge(df2,how='cross')
key_x value1 key_y value2
0 a 1 b 5
1 a 1 c 6
2 a 1 d 7
3 b 2 b 5
4 b 2 c 6
5 b 2 d 7
6 c 3 b 5
7 c 3 c 6
8 c 3 d 7
当两个数据框没有相同列时,需要设置left_on
和right_on
参数,表示按这两列进行连接。
# 数据准备
df3 = pd.DataFrame({'lkey': ['a', 'b', 'c'],
'value1': [1, 2, 3]})
df4 = pd.DataFrame({'rkey': ['b', 'c', 'd'],
'value2': [5, 6, 7]})
df3
lkey value1
0 a 1
1 b 2
2 c 3
df4
rkey value2
0 b 5
1 c 6
2 d 7
# 指定列内连接
df3.merge(df4, left_on='lkey', right_on='rkey')
lkey value1 rkey value2
0 b 2 b 5
1 c 3 c 6
如果需要根据数据框的索引进行连接,需要根据需求设置参数left_index=True
或者right_index=True
。
# 数据准备
df5 = pd.DataFrame({'lkey': ['a', 'b', 'c'],
'value1': [1, 2, 3]})
df6 = pd.DataFrame({'rkey': ['b', 'c', 'd'],
'value2': [5, 6, 7]},index=range(1,4))
df5
lkey value1
0 a 1
1 b 2
2 c 3
df6
rkey value2
1 b 5
2 c 6
3 d 7
# 按索引连接
df5.merge(df6,left_index=True,right_index=True)
lkey value1 rkey value2
1 b 2 b 5
2 c 3 c 6
设置suffixes
,可以给相同的列名添加后缀。默认后缀是_x
,_y
。
# 数据准备
df7 = pd.DataFrame({'key': ['a', 'b', 'c'],
'value': [1, 2, 3]})
df8 = pd.DataFrame({'key': ['b', 'c', 'd'],
'value': [5, 6, 7]})
df7
key value
0 a 1
1 b 2
2 c 3
df8
key value
0 b 5
1 c 6
2 d 7
# 连接后设置相同列后缀
df7.merge(df8,on='key',suffixes=['_A','_B'])
key value_A value_B
0 b 2 5
1 c 3 6
join
join
方法与merge
方法作用相同,基本上merge
方法已经可以完成所有的连接操作。
join
方法对按索引连接更方便而已。
# 数据准备
df1 = pd.DataFrame({'lkey': ['a', 'b', 'c'],
'value1': [1, 2, 3]},index=range(1,4))
df2 = pd.DataFrame({'rkey': ['b', 'c', 'd'],
'value2': [5, 6, 7]},index=range(2,5))
df1
lkey value1
1 a 1
2 b 2
3 c 3
df2
rkey value2
2 b 5
3 c 6
4 d 7
当连接的两个数据框中没有相同列时,可以直接按索引进行左连接。
# 通过索引左连接
df1.join(df2)
lkey value1 rkey value2
1 a 1 NaN NaN
2 b 2 b 5.0
3 c 3 c 6.0
同样,可以设置how
参数,控制连接的行为。
# 通过索引内连接
df1.join(df2,how='inner')
lkey value1 rkey value2
2 b 2 b 5
3 c 3 c 6
当数据框中有相同列时,需要设置后缀。
# 数据准备
df3 = pd.DataFrame({'key': ['a', 'b', 'c'],
'value1': [1, 2, 3]},index=range(1,4))
df4 = pd.DataFrame({'key': ['b', 'c', 'd'],
'value2': [5, 6, 7]},index=range(2,5))
# 为相同列设置后缀
df3.join(df4,lsuffix='_x',rsuffix='_y')
key_x value1 key_y value2
1 a 1 NaN NaN
2 b 2 b 5.0
3 c 3 c 6.0