Pandas: удалить уровень из многоуровневого индекса столбца?
Если у меня есть многоуровневый индекс столбца:
>>> cols = pd.MultiIndex.from_tuples([("a", "b"), ("a", "c")])
>>> pd.DataFrame([[1,2], [3,4]], columns=cols)
a
---+--
b | c
--+---+--
0 | 1 | 2
1 | 3 | 4
Как я могу сбросить уровень "а" этого индекса, поэтому в итоге получим:
b | c
--+---+--
0 | 1 | 2
1 | 3 | 4
Ответы
Ответ 1
Вы можете использовать MultiIndex.droplevel
:
>>> cols = pd.MultiIndex.from_tuples([("a", "b"), ("a", "c")])
>>> df = pd.DataFrame([[1,2], [3,4]], columns=cols)
>>> df
a
b c
0 1 2
1 3 4
[2 rows x 2 columns]
>>> df.columns = df.columns.droplevel()
>>> df
b c
0 1 2
1 3 4
[2 rows x 2 columns]
Ответ 2
Другой способ сбросить индекс - использовать понимание списка:
df.columns = [col[1] for col in df.columns]
b c
0 1 2
1 3 4
Эта стратегия также полезна, если вы хотите комбинировать имена с обоих уровней, как в примере ниже, где нижний уровень содержит два "y's:
cols = pd.MultiIndex.from_tuples([("A", "x"), ("A", "y"), ("B", "y")])
df = pd.DataFrame([[1,2, 8 ], [3,4, 9]], columns=cols)
A B
x y y
0 1 2 8
1 3 4 9
Отбрасывание верхнего уровня оставит два столбца с индексом 'y'. Этого можно избежать, соединяя имена со списком.
df.columns = ['_'.join(col) for col in df.columns]
A_x A_y B_y
0 1 2 8
1 3 4 9
Это проблема, с которой я столкнулся после группы, и потребовалось некоторое время, чтобы найти этот другой вопрос, который ее решил. Я адаптировал это решение для конкретного случая здесь.
Ответ 3
Другой способ сделать это - переназначить df
на основе сечения df
, используя метод .xs.
>>> df
a
b c
0 1 2
1 3 4
>>> df = df.xs('a', axis=1, drop_level=True)
# 'a' : key on which to get cross section
# axis=1 : get cross section of column
# drop_level=True : returns cross section without the multilevel index
>>> df
b c
0 1 2
1 3 4
Ответ 4
Вы также можете добиться этого, переименовав столбцы:
df.columns = ['a', 'b']
Это включает ручной шаг, но может быть вариант, особенно если вы в конечном итоге переименуете свой фрейм данных.
Ответ 5
Небольшой трюк с использованием sum
с уровнем = 1 (работает, когда уровень = 1 является уникальным)
df.sum(level=1,axis=1)
Out[202]:
b c
0 1 2
1 3 4
Более распространенное решение get_level_values
df.columns=df.columns.get_level_values(1)
df
Out[206]:
b c
0 1 2
1 3 4
Ответ 6
Я боролся с этой проблемой, так как я не знаю, почему моя функция droplevel() не работает. Проработайте несколько и узнайте, что 'a в вашей таблице - это имя столбца, а' b, 'c - это индекс. Делать как это поможет
df.columns.name = None
df.reset_index() #make index become label
Ответ 7
Начиная с Pandas 0.24.0, теперь мы можем использовать DataFrame.droplevel():
cols = pd.MultiIndex.from_tuples([("a", "b"), ("a", "c")])
df = pd.DataFrame([[1,2], [3,4]], columns=cols)
df.droplevel(0, axis=1)
# b c
#0 1 2
#1 3 4
Это очень полезно, если вы хотите поддерживать цепочку методов DataFrame.