Объединить серии Pandas и добавить название серии в многоуровневый индекс - PullRequest
1 голос
/ 15 октября 2019

У меня есть несколько именованных наборов данных серии 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 

1 Ответ

1 голос
/ 15 октября 2019

Используйте concat с Series.reorder_levels и 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
...