连接 Pandas 系列并将系列名称添加到多级索引

Concatenate Pandas series and add series name to multilevel index

我有多个命名为 Pandas 的系列数据集,具有匹配的多级索引

SeriesA = 

L1 L2 L3    value_a1
   L2 L3    value_a2
      L3    value_a3

SeriesA.name = First_Name


SeriesB =

L1 L2 L3    Value_b1
   L2 L3    Value_b2
      L3    Value_b3

SeriesB.name = Second_Name

我想做的是在连接它们之前将系列名称添加到现有系列索引中。预期输出应该是

SeriesAB =

L1  L2  L3 First_name    value_a1
    L2  L3 First_name    value_a2
        L3 First_name    value_a3
L1  L2  L3 Second_name   value_b1
    L2  L3 Second_name   value_b2
        L3 Second_name   value_b3

我尝试了 pd.join、pd.merge、pd.concat 的各种方法,但名称似乎是症结所在。

这样做的目的是在将名称值旋转到数据框之前合并名称值,以便数据看起来像这样。我猜 unstack 是解决这个问题的方法。

final_data =
            First_name  Second_name
L1  L2  L3  value_a1    value_b1
    L2  L3  value_a2    value_b2
        L3  value_a3    value_b3

我也想避免这种输出

Unwanted = 
               First_Name   Second_Name
L1   L2   L3   value_a1     NaN
     L2   L3   value_a2     NaN
          L3   value_a3     NaN
L1   L2   L3   NaN          value_b1
     L2   L3   NaN          value_b2
          L3   NaN          value_b3 

使用concat with Series.reorder_levels and Series.unstack.

concat 之后的关卡值重复,所以解决方案有点复杂 - 需要 GroupBy.cumcount:

的辅助关卡
df = (pd.concat([SeriesA, SeriesB], keys=('First_Name','Second_Name'))
        .reorder_levels([1,2,3,0])
        .to_frame('a'))
print (df)
                             a
L1 L2 L3 First_Name   value_a1
         First_Name   value_a2
         First_Name   value_a3
         Second_Name  value_b1
         Second_Name  value_b2
         Second_Name  value_b3

df = (df.set_index(df.groupby(df.index).cumcount(), append=True)['a']
        .unstack([3])
        .reset_index(level=3, drop=True))
print (df)
         First_Name Second_Name
L1 L2 L3   value_a1    value_b1
      L3   value_a2    value_b2
      L3   value_a3    value_b3

如果在concat之后没有重复,解决方案更简单:

print (SeriesA)
L1  L2  L3    value_a1
L2  L2  L3    value_a2
L3  L2  L3    value_a3
Name: a, dtype: object

print (SeriesB)
L1  L2  L3    value_b1
L2  L2  L3    value_b2
L3  L2  L3    value_b3
Name: a, dtype: object

df = (pd.concat([SeriesA, SeriesB], keys=('First_Name','Second_Name'))
        .reorder_levels([1,2,3,0])
        .unstack())
print (df)
         First_Name Second_Name
L1 L2 L3   value_a1    value_b1
L2 L2 L3   value_a2    value_b2
L3 L2 L3   value_a3    value_b3