it-roy-ru.com

Панды: сбросить уровень из многоуровневого индекса столбца?

Если у меня есть многоуровневый индекс столбца:

>>> 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 

Как я могу опустить уровень "a" этого индекса, чтобы я в итоге:

 b | c 
 - + --- + - 
 0 | 1 | 2 
 1 | 3 | 4 
173
David Wolever

Вы можете использовать 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]
206
DSM

Еще один способ отбросить индекс - использовать понимание списка: 

df.columns = [col[1] for col in df.columns]

   b  c
0  1  2
1  3  4

Эта стратегия также полезна, если вы хотите объединить имена с обоих уровней, как в примере ниже, где нижний уровень содержит два символа «у»:

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

Отбрасывание верхнего уровня оставило бы два столбца с индексом «у». Этого можно избежать, соединив имена с пониманием списка.

df.columns = ['_'.join(col) for col in df.columns]

    A_x A_y B_y
0   1   2   8
1   3   4   9

Это была проблема, с которой я столкнулся после работы в группе, и потребовалось время, чтобы найти этот другой вопрос , который решил ее. Я адаптировал это решение к конкретному случаю здесь.

38
Mint

Другой способ сделать это - переназначить 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
32
spacetyper

Этого также можно добиться, переименовав столбцы:

df.columns = ['a', 'b']

Это включает в себя ручной шаг, но может быть вариант, особенно если вы в конечном итоге переименовать свой фрейм данных.

13
sedeh

Небольшой трюк с использованием 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
4
Wen-Ben

Начиная с 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.

1
jxc

Я боролся с этой проблемой, так как не знаю, почему моя функция droplevel () не работает. Проработайте несколько и узнайте, что «a» в вашей таблице - это имя столбца, а «b», «c» - это индекс. Делать как это поможет

df.columns.name = None
df.reset_index() #make index become label
0
dhFrank