Pandas: Многоуровневые названия столбцов
Проблема с добавлением многоуровневых имен столбцов в pandas
Я использую библиотеку pandas
, которая поддерживает многоуровневые имена столбцов. Например, я создаю DataFrame следующим образом:
x = pd.DataFrame({'instance':['first','first','first'],'foo':['a','b','c'],'bar':rand(3)})
x = x.set_index(['instance','foo']).transpose()
print(x.columns)
В результате я получаю многоуровневыи индекс столбцов:
MultiIndex
[(u'first', u'a'), (u'first', u'b'), (u'first', u'c')]
И вывод выглядит так:
instance first
foo a b c
bar 0.102885 0.937838 0.907467
Эта функция очень полезна, так как позволяет "горизонтально" добавлять несколько версий одного и того же DataFrame, где первый уровень имен столбцов (в моем примере это instance
) различает экземпляры.
Теперь представьте, что у меня уже есть DataFrame, выглядящий так:
a b c
bar 0.102885 0.937838 0.907467
Я хотел бы узнать, есть ли удобный способ добавить другой уровень к именам столбцов, аналогично тому, как это делается для индекса строк:
x['instance'] = 'first'
x.set_level('instance', append=True)
Как я могу это сделать?
3 ответ(ов)
Попробуйте сделать следующее:
import pandas as pd
df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
columns = [('c', 'a'), ('c', 'b')]
df.columns = pd.MultiIndex.from_tuples(columns)
Этот код создает DataFrame
с именованными столбцами, используя MultiIndex
для их иерархической структуры. После выполнения этого кода у вас будет колонка "c", содержащая подколонки "a" и "b".
Многие из представленных решений кажутся чуть более сложными, чем нужно.
Я предпочитаю делать вещи как можно более простыми и интуитивно понятными, особенно когда скорость не является критически важной. Думаю, что это решение справляется с этой задачей.
Тестировалось в версиях pandas начиная с 0.22.0
.
Просто создайте DataFrame (игнорируйте столбцы на первом этапе), а затем присвойте поле columns
вашему n-мерному списку имен столбцов.
In [1]: import pandas as pd
In [2]: df = pd.DataFrame([[1, 1, 1, 1], [2, 2, 2, 2]])
In [3]: df
Out[3]:
0 1 2 3
0 1 1 1 1
1 2 2 2 2
In [4]: df.columns = [['a', 'c', 'e', 'g'], ['b', 'd', 'f', 'h']]
In [5]: df
Out[5]:
a c e g
b d f h
0 1 1 1 1
1 2 2 2 2
Этот подход позволяет легко и быстро создавать многоуровневые столбцы в DataFrame, что делает его более удобным для дальнейшей работы.
Вот функция, которая поможет вам создать кортеж для использования в pd.MultiIndex.from_tuples()
более универсально. Идея была подхвачена у @user3377361.
def create_tuple_for_for_columns(df_a, multi_level_col):
"""
Создает кортеж для колонок, который может быть использован в pandas MultiIndex для создания многоуровневых колонок.
:param df_a: pandas DataFrame, содержащий колонки, которые должны образовать первый уровень многоуровневого индекса
:param multi_level_col: имя колонки второго уровня
:return: кортеж, содержащий (колонка_второго_уровня, колонки_первого_уровня)
"""
temp_columns = []
for item in df_a.columns:
temp_columns.append((multi_level_col, item))
return temp_columns
Функцию можно использовать следующим образом:
df = pd.DataFrame({'a':[1,2,3],'b':[4,5,6]})
columns = create_tuple_for_for_columns(df, 'c')
df.columns = pd.MultiIndex.from_tuples(columns)
Это создаст многоуровневые колонки в вашем DataFrame, где 'c' будет именем второго уровня, а 'a' и 'b' – именами первого уровня.
Как изменить порядок столбцов в DataFrame?
Преобразование списка словарей в DataFrame pandas
Установить значение для конкретной ячейки в DataFrame pandas с использованием индекса
Выбор строки из pandas Series/DataFrame по целочисленному индексу
Получить все ключи из объекта GroupBy в Pandas