Pandas高级:合并数据集concat

本文主要介绍pandas中常用的数据合并的方法concat。

先定义一个生产数据的函数:

"""一个简单的DataFrame"""
def make_df(cols, ind): 
    data = {c: [str(c) + str(i) for i in ind]
            for c in cols}
    return pd.DataFrame(data, ind)

看下函数效果:

In:
make_df('AB', [1, 2])

Out:
        A	B
1	A1	B1
2	A2	B2

一.concat基础用法

pd.concat()可以简单地合并一维或多维的 Series 或 DataFrame 对象。

In:
df1 = make_df('AB', [1, 2])
df2 = make_df('AB', [3, 4])
print(df1); print(df2); 
print(pd.concat([df1, df2]))

Out:
    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=0)。pd.concat 也可以通过设置合并坐标轴 axis='col' axis=1 来实现按列合并。例如下面的示例:

In:
df3 = make_df('AB', [0, 1])
df4 = make_df('CD', [0, 1])
print(df3); print(df4); 
print(pd.concat([df3, df4], axis=1))

Out:
    A   B
0  A0  B0
1  A1  B1

    C   D
0  C0  D0
1  C1  D1

    A   B   C   D
0  A0  B0  C0  D0
1  A1  B1  C1  D1

二.重复索引问题

很多时候,将数据合并时,会出现重复索引的问题,如下:

In:
x = make_df('AB', [0, 1])
y = make_df('AB', [2, 3])
y.index = x.index # 复制索引
print(x); print(y); 
print(pd.concat([x, y]))

Out:
    A   B
0  A0  B0
1  A1  B1

    A   B
0  A2  B2
1  A3  B3

    A   B
0  A0  B0
1  A1  B1
0  A2  B2
1  A3  B3

针对这个问题,有两种处理方法:

1.忽略索引。有时索引无关紧要,那么合并时就可以忽略它们,可以通过设置 ignore_index 参数来实现。如果将参数设置为 True,那么合并时将会创建一个新的整数索引。

In:
x = make_df('AB', [0, 1])
y = make_df('AB', [2, 3])
y.index = x.index # 复制索引
print(x); print(y); print(pd.concat([x, y],ignore_index=True))

Out:
    A   B
0  A0  B0
1  A1  B1

    A   B
0  A2  B2
1  A3  B3

    A   B
0  A0  B0
1  A1  B1
2  A2  B2
3  A3  B3

(2) 增加多级索引。另一种处理索引重复的方法是通过 keys 参数为数据源设置多级索引标签,这样结果数据就会带上多级索引以便区分,如下:

In:
x = make_df('AB', [0, 1])
y = make_df('AB', [2, 3])
y.index = x.index # 复制索引
print(x); print(y); print(pd.concat([x, y],keys=['x','y']))

Out:
    A   B
0  A0  B0
1  A1  B1

    A   B
0  A2  B2
1  A3  B3

      A   B
x 0  A0  B0
  1  A1  B1
y 0  A2  B2
  1  A3  B3

三.join方法

使用concat方法合并数据集时有个弊端:如果按默认的逐行合并,那么两个数据集的列名需要一致。如果按列合并数据集,那么两个数据集的行数需要一致。否则就会出现如下NaN的情况。

In:
df1 = make_df('AB', [1, 2])
df2 = make_df('CD', [3, 4])
print(df1); print(df2); print(pd.concat([df1, df2]))

Out:
    A   B
1  A1  B1
2  A2  B2

    C   D
3  C3  D3
4  C4  D4

     A    B    C    D
1   A1   B1  NaN  NaN
2   A2   B2  NaN  NaN
3  NaN  NaN   C3   D3
4  NaN  NaN   C4   D4
In:
df3 = make_df('AB', [0, 1])
df4 = make_df('CDE', [0, 1,2])
print(df3); print(df4); print(pd.concat([df3, df4], axis=1))

Out:
    A   B
0  A0  B0
1  A1  B1

    C   D   E
0  C0  D0  E0
1  C1  D1  E1
2  C2  D2  E2

     A    B   C   D   E
0   A0   B0  C0  D0  E0
1   A1   B1  C1  D1  E1
2  NaN  NaN  C2  D2  E2

针对这个问题,可以用 joinjoin_ axes 参数设置合并方式。默认的合并方式是对所有输入列进行并集合并( join='outer' ), 当然也可以用 join='inner' 实现对输入列的交集合并:

In:
df5 = make_df('ABC', [1, 2])
df6 = make_df('BCD', [3, 4])
print(df5); print(df6); 
print(pd.concat([df5, df6], join='inner'))

Out:
    A   B   C
1  A1  B1  C1
2  A2  B2  C2

    B   C   D
3  B3  C3  D3
4  B4  C4  D4

    B   C
1  B1  C1
2  B2  C2
3  B3  C3
4  B4  C4

另一种合并方式是直接确定结果使用的列名,设置 join_axes 参数,里面是索引对象构成 的列表(是列表的列表)。如下面示例所示,将结果的列名设置为第一个输入的列名:

In:
df5 = make_df('ABC', [1, 2])
df6 = make_df('BCD', [3, 4])
print(df5); print(df6); 
print(pd.concat([df5, df6], join_axes=[df5.columns]))

Out:
    A   B   C
1  A1  B1  C1
2  A2  B2  C2

    B   C   D
3  B3  C3  D3
4  B4  C4  D4

     A   B   C
1   A1  B1  C1
2   A2  B2  C2
3  NaN  B3  C3
4  NaN  B4  C4

四. append方法


因为直接进行数组合并的需求非常普遍,所以 Series 和 DataFrame 对象都支持 append 方法,让你通过最少的代码实现合并功能。例如,你可以使用 df1.append(df2),效果与 pd.concat([df1, df2]) 一样。

关于concat方法就介绍这么多。

本文摘自《Python数据科学手册》

猜你喜欢

转载自blog.csdn.net/opp003/article/details/86589602