首页 > 解决方案 > 使用具有不同级别的 MultiIndex-ed 列加入/ Marge 的 DataFrame

问题描述

我有这个具有不同 MultiIndex 级别的虚拟 DataFrame:

A = pandas.DataFrame({"A" : [1, 5], "B" : [3, 5], "Output1" : [6, 8]}).set_index(["A", "B"]).unstack().fillna(0)

  Output1     
B       3    5
A             
1     6.0  0.0
5     0.0  8.0


B = pandas.DataFrame({"A" : [1, 6], "B" : [3, 5], "C" : [33, 55], "Output2" : [6, 7, 8]}).set_index(["A", "B", "C"]).unstack([1, 2]).fillna(0)


  Output2     
B       3    5
C      33   55
A             
1     6.0  0.0
6     0.0  8.0

我想加入两个 DataFrame-s 并得到以下结果:

   (Output2, 3, 33)  (Output2, 5, 55)  (Output1, 3)  (Output1, 5)
A                                                                
1               6.0               0.0           6.0           0.0
5               0.0               0.0           0.0           8.0
6               0.0               8.0           0.0           0.0 

我能够使用

res = B.join(A, how='outer').fillna(0)

但是,当我反转 A 和 B 时,B 的第一级索引消失了……并且级别数似乎被强制输入到连接断言的第一个 DataFrame 中。

达到预期结果的优雅方法是什么?

当前解决方案的第二个问题是可以按如下方式查询 DataFrame A 或 B:

A["Output1"]
B["Output2"]

但由于 MultiIndex-s 似乎被展平,因此无法以这种方式查询结果:

res["Output1"] #crash
res["Output2"] #crash

标签: pythonpandasdataframejoinouter-join

解决方案


一种方法是:

A.columns = pd.MultiIndex.from_tuples([(*t, '-') for t in list(A.columns)])
res = pd.concat((B, A), axis=1).fillna(0)
print(res)

输出

  Output2      Output1     
B       3    5       3    5
C      33   55       -    -
A                          
1     6.0  0.0     6.0  0.0
5     0.0  0.0     0.0  8.0
6     0.0  8.0     0.0  0.0

然后你可以这样做:

print(res['Output1'])

输出

B    3    5
C    -    -
A          
1  6.0  0.0
5  0.0  8.0
6  0.0  0.0

如果你不想修改A,你可以这样做:

new_A = A.reindex(columns=pd.MultiIndex.from_tuples([(*t, '-') for t in list(A.columns)]))
res = pd.concat((B, new_A), axis=1).fillna(0)

推荐阅读