Tri multi-index dans les pandas

88

J'ai un ensemble de données avec des colonnes multi-index dans un pandas df que je voudrais trier par valeurs dans une colonne spécifique. J'ai essayé d'utiliser sortindex et sortlevel mais je n'ai pas pu obtenir les résultats que je recherchais. Mon ensemble de données ressemble à:

    Group1    Group2
    A B C     A B C
1   1 0 3     2 5 7
2   5 6 9     1 0 0
3   7 0 2     0 3 5 

Je veux trier toutes les données et l'index par colonne C dans le groupe 1 dans l'ordre décroissant afin que mes résultats ressemblent à:

    Group1    Group2
    A B C     A B C
 2  5 6 9     1 0 0
 1  1 0 3     2 5 7
 3  7 0 2     0 3 5 

Est-il possible de faire ce tri avec la structure dans laquelle se trouvent mes données ou devrais-je échanger Group1 vers le côté index?

MattB
la source

Réponses:

129

Lors du tri par MultiIndex, vous devez contenir le tuple décrivant la colonne dans une liste *:

In [11]: df.sort_values([('Group1', 'C')], ascending=False)
Out[11]: 
  Group1       Group2      
       A  B  C      A  B  C
2      5  6  9      1  0  0
1      1  0  3      2  5  7
3      7  0  2      0  3  5

* pour ne pas confondre les pandas en pensant que vous voulez trier d'abord par Groupe1 puis par C.


Remarque: Initialement utilisé .sortdepuis obsolète puis supprimé dans 0.20, au profit de .sort_values.

Andy Hayden
la source
Merci, exactement ce que je cherchais.
MattB
Hmmph. Plus rapide que moi et une meilleure solution pour démarrer.
DSM
2
Exactement ce dont j'avais besoin, merci. Ce n'était pas clair dans la documentation (du moins je ne l'ai pas trouvé). En outre, le message d'erreur lorsque seulement de définir le niveau supérieur est trompeur: Cannot sort by duplicate column X.
Dr.Jan-Philip Gehrcke
Remerciements supplémentaires pour avoir ajouté l'explication pour laquelle nous devons utiliser une liste. Je souhaite que Pandas détecte la liste contre le tuple et interprète un tuple comme une sélection de colonne et non une liste de colonnes ...
Kaushik Ghose
5
@KaushikGhose qui semble être une bonne demande de fonctionnalité , je suppose que vous pouvez utiliser loc:df.loc[('Group1', 'C')]
Andy Hayden