合并與連接操作是數(shù)據(jù)處理中常見的,在pandas中用concat或append方法實現(xiàn)數(shù)據(jù)框的合并操作,
用merge或join方法實現(xiàn)數(shù)據(jù)框的連接操作。
環(huán)境
- python3.9
- win10 64bit
- pandas==1.2.1
append
append方法根據(jù)行在原數(shù)據(jù)框添加新的數(shù)據(jù)框。
import pandas as pd
pd.set_option('display.notebook_repr_html',False)
# 數(shù)據(jù)準(zhǔn)備
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
# 行末添加新數(shù)據(jù)框
df.append(df2)
A B
0 1 2
1 3 4
0 5 6
1 7 8
如果想要合并后的數(shù)據(jù)框索引重寫排序,可以設(shè)置參數(shù)ignore_index=True。
# 行末添加新數(shù)據(jù)框(索引重新排序)
df.append(df2,ignore_index=True)
A B
0 1 2
1 3 4
2 5 6
3 7 8
concat
concat函數(shù)是panda自帶的,可以按行或按列合并多個pandas數(shù)據(jù)框。
# 數(shù)據(jù)準(zhǔn)備
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
按行合并多個數(shù)據(jù)框,需要注意的是objs參數(shù)接受一個可迭代對象。concat函數(shù)默認(rèn)按行合并。
# 按行合并
pd.concat(objs=[df1,df2])
letter number
0 a 1
1 b 2
0 c 3
1 d 4
設(shè)置ignore_index=True,使合并后的數(shù)據(jù)框索引重新排序。
# 按行合并(索引重排序)
pd.concat([df1,df2],ignore_index=True)
letter number
0 a 1
1 b 2
2 c 3
3 d 4
按行合并時,concat對所有的列進(jìn)行全連接(參數(shù)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
設(shè)置參數(shù)join='inner',可以只保留共有的列。
pd.concat([df1,df3],join='inner')
letter number
0 a 1
1 b 2
0 c 3
1 d 4
設(shè)置參數(shù)axis=1或axis='columns',可以按列合并多個數(shù)據(jù)框。
# 按列合并數(shù)據(jù)框
pd.concat([df1,df2],axis=1)
letter number letter number
0 a 1 c 3
1 b 2 d 4
merge
merge方法根據(jù)列或索引連接數(shù)據(jù)框。
# 數(shù)據(jù)準(zhǔn)備
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
當(dāng)兩個數(shù)據(jù)框只有一個相同列時,merge方法會自動根據(jù)相同列進(jìn)行內(nèi)連接,on參數(shù)可以省略。
# 內(nèi)連接,默認(rèn)相同列連接
df1.merge(df2)
key value1 value2
0 b 2 5
1 c 3 6
# 內(nèi)連接,指定列連接
df1.merge(df2,on='key')
key value1 value2
0 b 2 5
1 c 3 6
設(shè)置參數(shù)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
當(dāng)兩個數(shù)據(jù)框沒有相同列時,需要設(shè)置left_on和right_on參數(shù),表示按這兩列進(jìn)行連接。
# 數(shù)據(jù)準(zhǔn)備
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
# 指定列內(nèi)連接
df3.merge(df4, left_on='lkey', right_on='rkey')
lkey value1 rkey value2
0 b 2 b 5
1 c 3 c 6
如果需要根據(jù)數(shù)據(jù)框的索引進(jìn)行連接,需要根據(jù)需求設(shè)置參數(shù)left_index=True或者right_index=True。
# 數(shù)據(jù)準(zhǔn)備
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
設(shè)置suffixes,可以給相同的列名添加后綴。默認(rèn)后綴是_x,_y。
# 數(shù)據(jù)準(zhǔn)備
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
# 連接后設(shè)置相同列后綴
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方法已經(jīng)可以完成所有的連接操作。
join方法對按索引連接更方便而已。
# 數(shù)據(jù)準(zhǔn)備
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
當(dāng)連接的兩個數(shù)據(jù)框中沒有相同列時,可以直接按索引進(jìn)行左連接。
# 通過索引左連接
df1.join(df2)
lkey value1 rkey value2
1 a 1 NaN NaN
2 b 2 b 5.0
3 c 3 c 6.0
同樣,可以設(shè)置how參數(shù),控制連接的行為。
# 通過索引內(nèi)連接
df1.join(df2,how='inner')
lkey value1 rkey value2
2 b 2 b 5
3 c 3 c 6
當(dāng)數(shù)據(jù)框中有相同列時,需要設(shè)置后綴。
# 數(shù)據(jù)準(zhǔn)備
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))
# 為相同列設(shè)置后綴
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