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() 函数一次性解决所有合并任务。