@@ -3096,17 +3096,19 @@ def reorder_levels(self, order):
30963096 def __getslice__ (self , i , j ):
30973097 return self .__getitem__ (slice (i , j ))
30983098
3099- def sortlevel (self , level = 0 , ascending = True ):
3099+ def sortlevel (self , level = 0 , ascending = True , sort_remaining = True ):
31003100 """
31013101 Sort MultiIndex at the requested level. The result will respect the
31023102 original ordering of the associated factor at that level.
31033103
31043104 Parameters
31053105 ----------
3106- level : int or str, default 0
3106+ level : list-like, int or str, default 0
31073107 If a string is given, must be a name of the level
3108+ If list-like must be names or ints of levels.
31083109 ascending : boolean, default True
31093110 False to sort in descending order
3111+ sort_remaining : sort by the remaining levels after level.
31103112
31113113 Returns
31123114 -------
@@ -3115,24 +3117,35 @@ def sortlevel(self, level=0, ascending=True):
31153117 from pandas .core .groupby import _indexer_from_factorized
31163118
31173119 labels = list (self .labels )
3120+ shape = list (self .levshape )
31183121
3119- level = self ._get_level_number (level )
3120- primary = labels .pop (level )
3122+ if isinstance (level , (str , int )):
3123+ level = [level ]
3124+ level = [self ._get_level_number (lev ) for lev in level ]
31213125
3122- shape = list (self .levshape )
3123- primshp = shape .pop (level )
3126+ # partition labels and shape
3127+ primary = tuple (labels .pop (lev - i ) for i , lev in enumerate (level ))
3128+ primshp = tuple (shape .pop (lev - i ) for i , lev in enumerate (level ))
31243129
3125- indexer = _indexer_from_factorized ((primary ,) + tuple (labels ),
3126- (primshp ,) + tuple (shape ),
3130+ if sort_remaining :
3131+ primary += primary + tuple (labels )
3132+ primshp += primshp + tuple (shape )
3133+ sortorder = None
3134+ else :
3135+ sortorder = level [0 ]
3136+
3137+ indexer = _indexer_from_factorized (primary ,
3138+ primshp ,
31273139 compress = False )
3140+
31283141 if not ascending :
31293142 indexer = indexer [::- 1 ]
31303143
31313144 indexer = com ._ensure_platform_int (indexer )
31323145 new_labels = [lab .take (indexer ) for lab in self .labels ]
31333146
31343147 new_index = MultiIndex (labels = new_labels , levels = self .levels ,
3135- names = self .names , sortorder = level ,
3148+ names = self .names , sortorder = sortorder ,
31363149 verify_integrity = False )
31373150
31383151 return new_index , indexer
0 commit comments