2 votes

Suppression sélective des colonnes d'un cadre de données à indexation multiniveau

Disons que nous avons un cadre de données comme celui-ci et que nous voulons supprimer des colonnes lorsque certaines conditions sont remplies.

    df = pd.DataFrame(
np.arange(2, 14).reshape(-1, 4),
index=list('ABC'),
columns=pd.MultiIndex.from_arrays([
    ['data1', 'data2','data1','data2'],
    ['F', 'K','R','X'],
    ['C', 'D','E','E']
], names=['meter', 'Sleeper','sweeper'])
)

df

enter image description here

alors disons que nous voulons supprimer les colonnes seulement quand meter == data1 y sweeper == E alors j'ai essayé

df = df.drop(('data1','E'),axis = 1)

KeyError : 'E

deuxième essai

df.drop(('data1','E'), axis = 1, level = 2)

KeyError : "étiquettes [('data1', 'E')] non trouvées dans le niveau"

Pandas : suppression d'un niveau dans un index de colonne multi-niveaux ?

2voto

Henry Ecker Points 15100

Il semble que drop ne prend pas en charge la sélection sur des niveaux fractionnés ( [0,2] ici). Nous pouvons créer un masque avec les conditions à la place en utilisant get_level_values :

# keep where not ((level0 is 'data1') and (level2 is 'E'))
col_mask = ~((df.columns.get_level_values(0) == 'data1')
             & (df.columns.get_level_values(2) == 'E'))
df = df.loc[:, col_mask]

Nous pouvons également le faire par emplacement entier en excluant les emplacements qui se trouvent dans une tranche d'index particulière, mais cette méthode est globalement moins claire et moins souple :

idx = pd.IndexSlice['data1', :, 'E']
cols = [i for i in range(len(df.columns))
        if i not in df.columns.get_locs(idx)]
df = df.iloc[:, cols]

L'une ou l'autre de ces approches produit df :

meter   data1 data2    
Sleeper     F     K   X
sweeper     C     D   E
A           2     3   5
B           6     7   9
C          10    11  13

1voto

sammywemmy Points 14854

Vous devez les faire individuellement, car ils sont à des niveaux différents :

df.drop('data1', axis=1, level='meter').drop('E', axis = 1, level='sweeper')
Out[833]: 
meter   data2
Sleeper     K
sweeper     D
A           3
B           7
C          11

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X