将形状相同的数据帧合并到multiIndex数据帧中

时间:2017-11-01 15:33:41

标签: python pandas dataframe merge

我有两个形状相同的pandas数据帧:

index = range(5)
columns = ['A', 'B', 'C']
left = pd.DataFrame(np.random.randint(1,10, size=(5,3)), index=index, columns=columns)
right = pd.DataFrame(np.random.randint(1,10, size=(5,3)), index=index, columns=columns)

left
Out[127]: 
   A  B  C
0  3  4  7
1  5  8  4
2  8  8  7
3  1  3  5
4  3  5  8

right
Out[129]: 
   A  B  C
0  2  8  2
1  3  6  5
2  4  6  4
3  8  4  2
4  4  2  9

现在我想将它们组合成一个具有相同索引和两个列级别的数据帧。在顶部是公共列名称,在底部是原始数据框名称:

combined = pd.DataFrame(np.nan, index=index, columns=pd.MultiIndex.from_tuples([('A', 'left'), ('A', 'right'), ('B', 'left'), ('B', 'right'), ('C', 'left'), ('C', 'right')]))
for column in combined.columns:
    if column[1] == 'left':
        combined[column] = left[column[0]]
    elif column[1] == 'right':
        combined[column] = right[column[0]]

combined
Out[138]: 
     A          B          C      
  left right left right left right
0    3     2    4     8    7     2
1    5     3    8     6    4     5
2    8     4    8     6    7     4
3    1     8    3     4    5     2
4    3     4    5     2    8     9

由于我正在处理的数据帧很大,是否有更快或更优雅的方法来实现这一目标?

提前致谢!

2 个答案:

答案 0 :(得分:2)

您可以在pd.concat中提供参数,以添加其他列级别:

pd.concat([left, right], axis=1, keys=['left', 'right']).swaplevel(axis=1).sort_index(axis=1)

#     A          B          C      
#  left right left right left right
#0    9     7    3     4    4     2
#1    8     3    9     1    3     5
#2    3     6    1     6    5     7
#3    9     1    7     2    2     2
#4    9     5    3     1    4     3

答案 1 :(得分:2)

我们可以使用add后缀然后拆分并将其转换为多索引,即

ndf = pd.concat([left.add_suffix(' left'),right.add_suffix(' right')],1).sort_index(1)
x = ndf.columns.str.split(' ')
ndf.columns = pd.MultiIndex.from_arrays([x.str[0],x.str[1]])
    A          B          C      
  left right left right left right
0    1     2    4     1    8     3
1    3     5    9     8    2     7
2    2     7    8     5    6     3
3    2     2    3     9    5     6
4    9     4    3     6    3     9