Простой способ создания многоиндексных столбцов с пандами

#pandas

Вопрос:

Извините за вопрос, но я не получил все еще существующих ответов. Я просто склеил два фрейма данных с одинаковыми именами столбцов.

 | | X | Y | X | Y | |---:|----:|----:|----:|----:| | 0 | 1 | 3 | 9 | 7 | | 1 | 2 | 4 | 8 | 6 |  

Чего я хочу, так это

 | | FOO | BAR | | | X | Y | X | Y | |---:|----:|----:|----:|----:| | 0 | 1 | 3 | 9 | 7 | | 1 | 2 | 4 | 8 | 6 |  

Я пытался pd.MultiIndex.from_product([c.columns, ['FOO', 'BAR']]) , но это приводит к

 MultiIndex([('X', 'FOO'),  ('X', 'BAR'),  ('Y', 'FOO'),  ('Y', 'BAR'),  ('X', 'FOO'),  ('X', 'BAR'),  ('Y', 'FOO'),  ('Y', 'BAR')],  )  

Но мне нужно

 MultiIndex([('X', 'FOO'),  ('Y', 'FOO'),  ('X', 'BAR'),  ('Y', 'BAR')],  )  

Это MWE

 #!/usr/bin/env python3 import pandas as pd  a = pd.DataFrame({'X': [1,2], 'Y': [3, 4]}) b = pd.DataFrame({'X': [9,8], 'Y': [7, 6]})  c = pd.concat([a, b], axis=1)  # throws a ValueError: Length mismatch: Expected axis has 4 elements, new values have 8 elements c.columns = pd.MultiIndex.from_product([c.columns, ['FOO', 'BAR']])  

Поможет ли это что-то сделать с двумя отдельными кадрами данных, прежде чем я concat() их удалю?

Комментарии:

1. pd.MultiIndex.from_product([df.columns.unique(), ['FOO', 'BAR']]) ?

2. c.columns = pd.MultiIndex.from_arrays((pd.Index(['FOO', 'BAR']).repeat(2), c.columns))

Ответ №1:

Вы можете просто добавить дополнительный уровень, используя numpy.repeat и pandas.MultiIndex :

 import numpy as np  extra = ['FOO', 'BAR'] c.columns = pd.MultiIndex.from_arrays([np.repeat(extra, len(c.columns)//len(extra)),  c.columns])  

выход:

 FOO BAR   X Y X Y 0 1 3 9 7 1 2 4 8 6  

nb. Если столбцы перемешаны, отсортируйте их и используйте np.tile вместо этого:

 c = c.sort_index(axis=1)  extra = ['FOO', 'BAR'] c.columns = pd.MultiIndex.from_arrays([np.tile(extra, len(c.columns)//len(extra)),  c.columns])  

выход:

 FOO BAR FOO BAR  X X Y Y 0 1 9 3 7 1 2 8 4 6