@@ -1173,98 +1173,98 @@ def from_product(cls, iterables, sortorder=None, names=None):
11731173 labels  =  cartesian_product (labels )
11741174 return  MultiIndex (levels , labels , sortorder = sortorder , names = names )
11751175
1176-  def  _reconstruct (self ,  sort = False ,  remove_unused = False ):
1176+  def  sort_monotonic (self ):
11771177 """ 
1178-  create a new MultiIndex from the current to provide either: 
1179-  - monotonically sorted items IN the levels 
1180-  - removing unused levels (meaning that they are not expressed 
1181-  in the labels) 
1178+  create a new MultiIndex from the current to monotonically sorted 
1179+  items IN the levels 
11821180
11831181 The resulting MultiIndex will have the same outward 
11841182 appearance, meaning the same .values and ordering. It will also 
11851183 be .equals() to the original. 
11861184
1187-  Parameters 
1188-  ---------- 
1189-  sort: boolean, default False 
1190-  monotonically sort the levels 
1191-  remove_unused: boolean, default False 
1192-  remove unsued levels 
1193- 
11941185 Returns 
11951186 ------- 
1196-  new  MultiIndex 
1187+  MultiIndex 
11971188
11981189 """ 
11991190
1200-  if  sort  and  remove_unused :
1201-  raise  ValueError ("only support one of sort / remove_unused" )
1202- 
1203-  if  not  (sort  or  remove_unused ):
1204-  raise  ValueError ("must supply one of sort / remove_unsued" )
1205- 
1206-  levels  =  self .levels 
1207-  labels  =  self .labels 
1191+  if  self .is_lexsorted () and  self .is_monotonic :
1192+  return  self 
12081193
12091194 new_levels  =  []
12101195 new_labels  =  []
12111196
1212-  if  sort :
1213- 
1214-  if  self .is_lexsorted () and  self .is_monotonic :
1215-  return  self 
1197+  for  lev , lab  in  zip (self .levels , self .labels ):
12161198
1217-  for  lev , lab  in  zip (levels , labels ):
1199+  if  lev .is_monotonic :
1200+  new_levels .append (lev )
1201+  new_labels .append (lab )
1202+  continue 
12181203
1219-  if  lev .is_monotonic :
1220-  new_levels .append (lev )
1221-  new_labels .append (lab )
1222-  continue 
1204+  # indexer to reorder the levels 
1205+  indexer  =  lev .argsort ()
1206+  lev  =  lev .take (indexer )
12231207
1224-    # indexer to reorder the levels  
1225-    indexer   =   lev . argsort ( )
1226-    lev   =   lev . take ( indexer )
1208+  # indexer to reorder the labels  
1209+  ri   =   lib . get_reverse_indexer ( indexer ,  len ( indexer ) )
1210+  lab   =   algos . take_1d ( ri ,  lab )
12271211
1228-  # indexer to reorder the labels 
1229-  ri  =  lib .get_reverse_indexer (indexer , len (indexer ))
1230-  lab  =  algos .take_1d (ri , lab )
1212+  new_levels .append (lev )
1213+  new_labels .append (lab )
12311214
1232-  new_levels .append (lev )
1233-  new_labels .append (lab )
1234- 
1235-  elif  remove_unused :
1215+  return  MultiIndex (new_levels , new_labels ,
1216+  names = self .names , sortorder = self .sortorder ,
1217+  verify_integrity = False )
12361218
1237-  changed  =  np .zeros (self .nlevels , dtype = bool )
1238-  for  i , (lev , lab ) in  enumerate (zip (levels , labels )):
1219+  def  remove_unused_levels (self ):
1220+  """ 
1221+  create a new MultiIndex from the current that removesing 
1222+  unused levels, meaning that they are not expressed in the labels 
12391223
1240-  uniques  =  np .sort (algos .unique (lab ))
1224+  The resulting MultiIndex will have the same outward 
1225+  appearance, meaning the same .values and ordering. It will also 
1226+  be .equals() to the original. 
12411227
1242-  # nothing unused 
1243-  if  len (uniques ) ==  len (lev ):
1244-  new_levels .append (lev )
1245-  new_labels .append (lab )
1246-  changed [i ] =  True 
1247-  continue 
1228+  Returns 
1229+  ------- 
1230+  MultiIndex 
12481231
1249-  unused  =  list (reversed (sorted (set (
1250-  np .arange (len (lev ))) -  set (uniques ))))
1232+  """ 
12511233
1252-    # new levels are simple 
1253-    lev   =   lev . take ( uniques ) 
1234+  new_levels   =  [] 
1235+  new_labels   =  [] 
12541236
1255-  # new labels, we remove the unsued 
1256-  # by decrementing the labels for that value 
1257-  # prob a better way 
1258-  for  u  in  unused :
1237+  changed  =  np .zeros (self .nlevels , dtype = bool )
1238+  for  i , (lev , lab ) in  enumerate (zip (self .levels , self .labels )):
12591239
1260-    lab   =  np .where ( lab   >   u ,  lab   -   1 ,  lab )
1240+  uniques   =  np .sort ( algos . unique ( lab ) )
12611241
1242+  # nothing unused 
1243+  if  len (uniques ) ==  len (lev ):
12621244 new_levels .append (lev )
12631245 new_labels .append (lab )
1246+  changed [i ] =  True 
1247+  continue 
1248+ 
1249+  unused  =  list (reversed (sorted (set (
1250+  np .arange (len (lev ))) -  set (uniques ))))
1251+ 
1252+  # new levels are simple 
1253+  lev  =  lev .take (uniques )
12641254
1265-  # nothing changed 
1266-  if  not  changed .any ():
1267-  return  self 
1255+  # new labels, we remove the unsued 
1256+  # by decrementing the labels for that value 
1257+  # prob a better way 
1258+  for  u  in  unused :
1259+ 
1260+  lab  =  np .where (lab  >  u , lab  -  1 , lab )
1261+ 
1262+  new_levels .append (lev )
1263+  new_labels .append (lab )
1264+ 
1265+  # nothing changed 
1266+  if  not  changed .any ():
1267+  return  self 
12681268
12691269 return  MultiIndex (new_levels , new_labels ,
12701270 names = self .names , sortorder = self .sortorder ,
0 commit comments