Панды - Добавить уровень столбца в мультииндекс - PullRequest
2 голосов
/ 07 ноября 2019

Я хотел бы добавить подуровень (L4) в моем фрейме данных на основе списка значений:

x = [0.01, 0.01, 0.01, 0.02, 0.02, 0.02]

df.columns возвращает мне это:

MultiIndex(levels=[['Foo', 'Bar'], ['A', 'B', 'C'], ['a']],
           labels=[[0, 0, 0, 1, 1, 1], [0, 1, 2, 0, 1, 2], [0, 0, 0, 0, 0, 0]],
           names=['L1', 'L2', 'L3'])

До сих пор я пробовал это:

df = pd.concat([df], keys=x, names=['L4'], axis=1).swaplevel(i='L4', j='L1', axis=1).swaplevel(i='L4', j='L2', axis=1).swaplevel(i='L4', j='L3', axis=1)

, но это не дает хорошего значения, оно повторяет list_levels [0] (0,01).

Есть ли у вас какие-либо идеи о том, как яможет это сделать?

Спасибо

Ответы [ 2 ]

0 голосов
/ 07 ноября 2019

Вот способ:

cols = pd.MultiIndex(levels=[['Foo', 'Bar'], ['A', 'B', 'C'], ['a']],
       labels=[[0, 0, 0, 1, 1, 1], [0, 1, 2, 0, 1, 2], [0, 0, 0, 0, 0, 0]],
       names=['L1', 'L2', 'L3'])

pd.DataFrame(columns = cols).T\
  .assign(x = [0.01, 0.01, 0.01, 0.02, 0.02, 0.02])\
  .set_index('x', append=True).T

Вывод:

enter image description here

0 голосов
/ 07 ноября 2019

Вы можете создать DataFrame с индексом столбца в качестве индекса, а data - это уровень, который вы хотите добавить, так как set_index(append=True) определяется только для строки индекса. Затем назначьте его с помощью df.columns = ...

import pandas as pd

idx = pd.MultiIndex(levels=[['Foo', 'Bar'], ['A', 'B', 'C'], ['a']],
                codes=[[0, 0, 0, 1, 1, 1], [0, 1, 2, 0, 1, 2], [0, 0, 0, 0, 0, 0]],
                names=['L1', 'L2', 'L3'])
x = [0.01, 0.01, 0.01, 0.02, 0.02, 0.02]

pd.DataFrame(x, index=idx, columns=['L4']).set_index('L4', append=True).index
#MultiIndex([('Foo', 'A', 'a', 0.01),
#            ('Foo', 'B', 'a', 0.01),
#            ('Foo', 'C', 'a', 0.01),
#            ('Bar', 'A', 'a', 0.02),
#            ('Bar', 'B', 'a', 0.02),
#            ('Bar', 'C', 'a', 0.02)],
#           names=['L1', 'L2', 'L3', 'L4'])

Под капотом set_index просто воссоздает весь MultiIndex при добавлении, так что более практический подход -

arrays = []
for i in range(idx.nlevels):
    arrays.append(idx.get_level_values(i))

arrays.append(pd.Index(x, name='L4'))  # Add the new level

new_idx = pd.MultiIndex.from_arrays(arrays)
#MultiIndex([('Foo', 'A', 'a', 0.01),
#            ('Foo', 'B', 'a', 0.01),
#            ('Foo', 'C', 'a', 0.01),
#            ('Bar', 'A', 'a', 0.02),
#            ('Bar', 'B', 'a', 0.02),
#            ('Bar', 'C', 'a', 0.02)],
#           names=['L1', 'L2', 'L3', 'L4'])
...