web-dev-qa-db-fra.com

Pandas: abandonner un niveau d'un index de colonnes multi-niveaux?

Si j'ai un index de colonne multi-niveaux:

>>> cols = pd.MultiIndex.from_tuples([("a", "b"), ("a", "c")])
>>> pd.DataFrame([[1,2], [3,4]], columns=cols)
 une
 --- + --
 b | c 
-- + --- + --
 0 | 1 | 2 
 1 | 3 | 4 

Comment puis-je supprimer le niveau "a" de cet index, de sorte que je me retrouve avec:

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

Vous pouvez utiliser 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

Une autre façon de supprimer l'index consiste à utiliser une compréhension de liste: 

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

   b  c
0  1  2
1  3  4

Cette stratégie est également utile si vous souhaitez combiner les noms des deux niveaux, comme dans l'exemple ci-dessous où le niveau inférieur contient deux 'y:

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

Supprimer le niveau supérieur laisserait deux colonnes avec l'index 'y'. Cela peut être évité en joignant les noms à la liste de compréhension.

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

    A_x A_y B_y
0   1   2   8
1   3   4   9

C'est un problème que j'ai eu après avoir fait un groupe et il m'a fallu du temps pour trouver cette autre question qui l'a résolue. J'ai adapté cette solution au cas particulier ici.

38
Mint

Une autre méthode consiste à réaffecter df en fonction d'une section transversale de df, à l'aide de la méthode .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

Vous pouvez également y parvenir en renommant les colonnes:

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

Cela implique une étape manuelle, mais peut constituer une option, en particulier si vous souhaitez renommer votre trame de données.

13
sedeh

Une petite astuce utilisant sum avec niveau = 1 (travail lorsque niveau = 1 est unique)

df.sum(level=1,axis=1)
Out[202]: 
   b  c
0  1  2
1  3  4

Solution plus commune 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

À partir de Pandas 0.24.0 , nous pouvons maintenant utiliser 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

Ceci est très utile si vous souhaitez que votre chaîne de méthodes DataFrame continue à rouler.

3
jxc

Je suis aux prises avec ce problème car je ne sais pas pourquoi ma fonction droplevel () ne fonctionne pas. Parcourez plusieurs options et apprenez que «a» dans votre tableau correspond au nom des colonnes et que «b», «c» sont des index. Faire comme ça aidera

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