3.7 合併數據集:Concat與Append操作
將不同的數據源進行合併是數據處理中最常見的操作,包括將兩個不同數據集簡單地拼接,也包括處理有重疊字段的數據集。Series與DataFrame都具備這類操作,Pandas的函數與方法讓數據合併變得更加快速.
In [1] :import numpy as np
import pandas as pd
爲了簡單起見,定義一個能夠創建DataFrame某種形式的函數:
In [2] :def make_df(cols,ind):
data = {c: [str(c) + str(i) for i in ind] for c in cols}
return pd.DataFrame(data, ind)
3.7.1 Numpy數組的合併
合併Series與DataFrame 與 Numpy數組基本相同。
In [3] :x = [1, 2, 3]
y = [4, 5, 6]
z = [7, 8, 9]
In [4] :np.concatenate([x,y,z]) # np.concatenate((x,y,z)) 元組也可以
Out[4] :array([1, 2, 3, 4, 5, 6, 7, 8, 9])
第一個參數是需要合併的數組或元組。還有一個axis參數可以設置合併的座標軸方向。
In [4] :x = [[1,2],[3,4]]
In [5] :np.concatenate([x,x],axis=0) # 默認在行方向合併,也就是增加行
Out[5] :array([[1, 2],
[3, 4],
[1, 2],
[3, 4]])
In [6] :np.concatenate([x,x],axis=1) # 在列方向合併,也就是增加列
Out[6] :array([[1, 2, 1, 2],
[3, 4, 3, 4]])
3.7.2 通過pd.concat實現簡易合併
Pandas有一個pd.concat()函數與np.concatenate()語法類似,pd.concat() 可以簡單地合併一維的Series 或DataFrame 對象,與np.concatenate() 合併數組一樣:
In [7] :ser1 = pd.Series(['A','B','C'],index=[1,2,3])
ser2 = pd.Series(['D','E','F'],index=[4,5,6])
pd.concat([ser1,ser2],axis=0)
Out[7] :
1 A
2 B
3 C
4 D
5 E
6 F
dtype: object
也可以用來合併高維數據,例如下面的DataFrame:
In [8] :df1 = make_df('AB', [1, 2])
df2 = make_df('AB', [3, 4])
print(df1); print(df2); print(pd.concat([df1, df2]))
Out[8] :
A B
1 A1 B1
2 A2 B2
A B
3 A3 B3
4 A4 B4
A B
1 A1 B1
2 A2 B2
3 A3 B3
4 A4 B4
默認情況下,DataFrame 的合併都是逐行進行的,如果需要按列合併,將axis設置爲1.
上面合併的DataFrame 都是同樣的列名。而在實際工作中,需要合併的數據往往帶有不同的列名,而pd.concat 提供了一些選項來解決這類合併問題。看下面兩個DataFrame,它們的列名部分相同,卻又不完全相同:
In [9] :df5 = make_df('ABC',[1,2])
df6 = make_df('BCD',[3,4])
pd.concat([df5,df6])
Out[9] :
A B C D
1 A1 B1 C1 NaN
2 A2 B2 C2 NaN
3 NaN B3 C3 D3
4 NaN B4 C4 D4
默認情況下,某個位置上缺失的數據會用NaN 表示。如果不想這樣,可以用join 和join_axes 參數設置合併方式。默認的合併方式是對所有輸入列進行並集合並(join=‘outer’),當然也可以用join=‘inner’ 實現對輸入列的交集合並:
In [10] :pd.concat([df5,df6],join='inner')
Out[10] :
B C
1 B1 C1
2 B2 C2
3 B3 C3
4 B4 C4
3.7.3 append()方法
因爲直接進行數組合並的需求非常普遍,所以Series 和DataFrame 對象都支持append 方法,讓你通過最少的代碼實現合併功能。例如,你可以使用df1.append(df2),效果與pd.concat([df1, df2]) 一樣:
In [11] :df1.append(df2)
Out[11] :
A B
1 A1 B1
2 A2 B2
3 A3 B3
4 A4 B4
需要注意的是,與Python 列表中的append() 和extend() 方法不同,Pandas 的append() 不直接更新原有對象的值,而是爲合併後的數據創建一個新對象。因此,它不能被稱之爲一個非常高效的解決方案,因爲每次合併都需要重新創建索引和數據緩存。總之,如果你需要進行多個append 操作,還是建議先創建一個DataFrame 列表,然後用concat() 函數一次性解決所有合併任務。