J'ai un DataFrame avec un MultiIndex créé après un certain regroupement:
import numpy as np
import pandas as p
from numpy.random import randn
df = p.DataFrame({
'A' : ['a1', 'a1', 'a2', 'a3']
, 'B' : ['b1', 'b2', 'b3', 'b4']
, 'Vals' : randn(4)
}).groupby(['A', 'B']).sum()
df
Output> Vals
Output> A B
Output> a1 b1 -1.632460
Output> b2 0.596027
Output> a2 b3 -0.619130
Output> a3 b4 -0.002009
Comment ajouter un niveau au MultiIndex afin de le transformer en quelque chose comme:
Output> Vals
Output> FirstLevel A B
Output> Foo a1 b1 -1.632460
Output> b2 0.596027
Output> a2 b3 -0.619130
Output> a3 b4 -0.002009
axis=1
, car ledf.columns
n'a pas la méthode "set_index" comme l'index, ce qui me dérange toujours.pd.Series
objets, contrairement à la réponse actuellement acceptée (à partir de 2013).FirstLevel
comme dans['Foo', 'Bar']
le premier argument, vous devrez également avoir la longueur correspondante, c'est-à-dire[df] * len(['Foo', 'Bar'])
!pd.concat({'Foo': df}, names=['Firstlevel'])
Vous pouvez d'abord l'ajouter en tant que colonne normale, puis l'ajouter à l'index actuel, donc:
Et modifiez l'ordre si besoin avec:
Ce qui se traduit par:
la source
Je pense que c'est une solution plus générale:
Quelques avantages par rapport aux autres réponses:
la source
J'ai fait une petite fonction de la réponse de cxrodgers , qui à mon humble avis est la meilleure solution car elle fonctionne uniquement sur un index, indépendant de toute trame ou série de données.
Il y a un correctif que j'ai ajouté: la
to_frame()
méthode inventera de nouveaux noms pour les niveaux d'index qui n'en ont pas. En tant que tel, le nouvel index aura des noms qui n'existent pas dans l'ancien index. J'ai ajouté du code pour annuler ce changement de nom.Ci-dessous le code, je l'ai utilisé moi-même pendant un moment et il semble fonctionner correctement. Si vous trouvez des problèmes ou des cas extrêmes, je serais bien obligé d'ajuster ma réponse.
Il a passé le code unittest suivant:
la source
Que diriez-vous de le créer à partir de zéro avec pandas.MultiIndex.from_tuples ?
De la même manière que la solution de cxrodger , il s'agit d'une méthode flexible et évite de modifier le tableau sous-jacent pour le dataframe.
la source