J'ai une trame de données avec Multiindex et je voudrais modifier un niveau particulier du Multiindex. Par exemple, le premier niveau peut être des chaînes et je peux supprimer les espaces blancs de ce niveau d'index:
df.index.levels[1] = [x.replace(' ', '') for x in df.index.levels[1]]
Cependant, le code ci-dessus entraîne une erreur:
TypeError: 'FrozenList' does not support mutable operations.
Je sais que je peux réinitialiser_index et modifier la colonne, puis recréer le Multiindex, mais je me demande s'il existe un moyen plus élégant de modifier directement un niveau particulier du Multiindex.
Grâce au commentaire de @ cxrodgers, je pense que le moyen le plus rapide de le faire est:
df.index = df.index.set_levels(df.index.levels[0].str.replace(' ', ''), level=0)
Vieille réponse plus longue:
J'ai trouvé que la compréhension de la liste suggérée par @Shovalt fonctionne mais me semblait lente sur ma machine (en utilisant une trame de données avec> 10 000 lignes).
Au lieu de cela, j'ai pu utiliser .set_levels
méthode, qui était un peu plus rapide pour moi.
%timeit pd.MultiIndex.from_tuples([(x[0].replace(' ',''), x[1]) for x in df.index])
1 loop, best of 3: 394 ms per loop
%timeit df.index.set_levels(df.index.get_level_values(0).str.replace(' ',''), level=0)
10 loops, best of 3: 134 ms per loop
En réalité, je devais juste ajouter du texte. C'était encore plus rapide avec .set_levels
:
%timeit pd.MultiIndex.from_tuples([('00'+x[0], x[1]) for x in df.index])
100 loops, best of 3: 5.18 ms per loop
%timeit df.index.set_levels('00'+df.index.get_level_values(0), level=0)
1000 loops, best of 3: 1.38 ms per loop
%timeit df.index.set_levels('00'+df.index.levels[0], level=0)
1000 loops, best of 3: 331 µs per loop
Cette solution est basée sur la réponse dans le lien du commentaire de @denfromufa ...
python - Multiindex et fuseau horaire - Erreur de liste gelée - Débordement de pile
Comme mentionné dans les commentaires, les index sont immuables et doivent être refaits lors de la modification, mais vous n'avez pas besoin d'utiliser reset_index
pour cela, vous pouvez créer directement un nouveau multi-index:
df.index = pd.MultiIndex.from_tuples([(x[0], x[1].replace(' ', ''), x[2]) for x in df.index])
Cet exemple concerne un index à 3 niveaux, dans lequel vous souhaitez modifier le niveau intermédiaire. Vous devez modifier la taille du tuple pour différentes tailles de niveau.