@@ -391,11 +391,11 @@ def _verify_integrity(
391391                    f"Level values must be unique: { list (level )} { i }  
392392                )
393393        if  self .sortorder  is  not None :
394-             if  self .sortorder  >  self . _lexsort_depth ():
394+             if  self .sortorder  >  _lexsort_depth (self . codes ,  self . nlevels ):
395395                raise  ValueError (
396396                    "Value for sortorder must be inferior or equal to actual " 
397397                    f"lexsort_depth: sortorder { self .sortorder }  
398-                     f"with lexsort_depth { self . _lexsort_depth ()}  
398+                     f"with lexsort_depth { _lexsort_depth (self . codes ,  self . nlevels )}  
399399                )
400400
401401        codes  =  [
@@ -1809,6 +1809,15 @@ def _is_all_dates(self) -> bool:
18091809        return  False 
18101810
18111811    def  is_lexsorted (self ) ->  bool :
1812+         warnings .warn (
1813+             "MultiIndex.is_lexsorted is deprecated as a public function, " 
1814+             "users should use MultiIndex.is_monotonic_increasing instead." ,
1815+             FutureWarning ,
1816+             stacklevel = 2 ,
1817+         )
1818+         return  self ._is_lexsorted ()
1819+ 
1820+     def  _is_lexsorted (self ) ->  bool :
18121821        """ 
18131822        Return True if the codes are lexicographically sorted. 
18141823
@@ -1840,15 +1849,19 @@ def is_lexsorted(self) -> bool:
18401849        ...                            ['bb', 'aa', 'aa', 'bb']]).is_lexsorted() 
18411850        False 
18421851        """ 
1843-         return  self .lexsort_depth  ==  self .nlevels 
1852+         return  self ._lexsort_depth  ==  self .nlevels 
18441853
1845-     @cache_readonly  
1854+     @property  
18461855    def  lexsort_depth (self ):
1847-         if  self .sortorder  is  not None :
1848-             return  self .sortorder 
1849- 
1850-         return  self ._lexsort_depth ()
1856+         warnings .warn (
1857+             "MultiIndex.is_lexsorted is deprecated as a public function, " 
1858+             "users should use MultiIndex.is_monotonic_increasing instead." ,
1859+             FutureWarning ,
1860+             stacklevel = 2 ,
1861+         )
1862+         return  self ._lexsort_depth 
18511863
1864+     @cache_readonly  
18521865    def  _lexsort_depth (self ) ->  int :
18531866        """ 
18541867        Compute and return the lexsort_depth, the number of levels of the 
@@ -1858,11 +1871,9 @@ def _lexsort_depth(self) -> int:
18581871        ------- 
18591872        int 
18601873        """ 
1861-         int64_codes  =  [ensure_int64 (level_codes ) for  level_codes  in  self .codes ]
1862-         for  k  in  range (self .nlevels , 0 , - 1 ):
1863-             if  libalgos .is_lexsorted (int64_codes [:k ]):
1864-                 return  k 
1865-         return  0 
1874+         if  self .sortorder  is  not None :
1875+             return  self .sortorder 
1876+         return  _lexsort_depth (self .codes , self .nlevels )
18661877
18671878    def  _sort_levels_monotonic (self ):
18681879        """ 
@@ -1898,7 +1909,7 @@ def _sort_levels_monotonic(self):
18981909                    ('b', 'bb')], 
18991910                   ) 
19001911        """ 
1901-         if  self .is_lexsorted () and  self .is_monotonic :
1912+         if  self ._is_lexsorted () and  self .is_monotonic :
19021913            return  self 
19031914
19041915        new_levels  =  []
@@ -2184,7 +2195,7 @@ def drop(self, codes, level=None, errors="raise"):
21842195                    step  =  loc .step  if  loc .step  is  not None  else  1 
21852196                    inds .extend (range (loc .start , loc .stop , step ))
21862197                elif  com .is_bool_indexer (loc ):
2187-                     if  self .lexsort_depth  ==  0 :
2198+                     if  self ._lexsort_depth  ==  0 :
21882199                        warnings .warn (
21892200                            "dropping on a non-lexsorted multi-index " 
21902201                            "without a level parameter may impact performance." ,
@@ -2755,10 +2766,10 @@ def slice_locs(self, start=None, end=None, step=None, kind=None):
27552766        return  super ().slice_locs (start , end , step , kind = kind )
27562767
27572768    def  _partial_tup_index (self , tup , side = "left" ):
2758-         if  len (tup ) >  self .lexsort_depth :
2769+         if  len (tup ) >  self ._lexsort_depth :
27592770            raise  UnsortedIndexError (
27602771                f"Key length ({ len (tup )}  
2761-                 f"({ self .lexsort_depth }  
2772+                 f"({ self ._lexsort_depth }  
27622773            )
27632774
27642775        n  =  len (tup )
@@ -2897,7 +2908,7 @@ def _maybe_to_slice(loc):
28972908        # break the key into 2 parts based on the lexsort_depth of the index; 
28982909        # the first part returns a continuous slice of the index; the 2nd part 
28992910        # needs linear search within the slice 
2900-         i  =  self .lexsort_depth 
2911+         i  =  self ._lexsort_depth 
29012912        lead_key , follow_key  =  key [:i ], key [i :]
29022913        start , stop  =  (
29032914            self .slice_locs (lead_key , lead_key ) if  lead_key  else  (0 , len (self ))
@@ -3150,7 +3161,7 @@ def convert_indexer(start, stop, step, indexer=indexer, codes=level_codes):
31503161                stop  =  getattr (stop , "stop" , stop )
31513162                return  convert_indexer (start , stop , step )
31523163
3153-             elif  level  >  0  or  self .lexsort_depth  ==  0  or  step  is  not None :
3164+             elif  level  >  0  or  self ._lexsort_depth  ==  0  or  step  is  not None :
31543165                # need to have like semantics here to right 
31553166                # searching as when we are using a slice 
31563167                # so include the stop+1 (so we include stop) 
@@ -3165,7 +3176,7 @@ def convert_indexer(start, stop, step, indexer=indexer, codes=level_codes):
31653176
31663177            idx  =  self ._get_loc_single_level_index (level_index , key )
31673178
3168-             if  level  >  0  or  self .lexsort_depth  ==  0 :
3179+             if  level  >  0  or  self ._lexsort_depth  ==  0 :
31693180                # Desired level is not sorted 
31703181                locs  =  np .array (level_codes  ==  idx , dtype = bool , copy = False )
31713182                if  not  locs .any ():
@@ -3222,10 +3233,10 @@ def get_locs(self, seq):
32223233
32233234        # must be lexsorted to at least as many levels 
32243235        true_slices  =  [i  for  (i , s ) in  enumerate (com .is_true_slices (seq )) if  s ]
3225-         if  true_slices  and  true_slices [- 1 ] >=  self .lexsort_depth :
3236+         if  true_slices  and  true_slices [- 1 ] >=  self ._lexsort_depth :
32263237            raise  UnsortedIndexError (
32273238                "MultiIndex slicing requires the index to be lexsorted: slicing " 
3228-                 f"on levels { true_slices } { self .lexsort_depth }  
3239+                 f"on levels { true_slices } { self ._lexsort_depth }  
32293240            )
32303241        # indexer 
32313242        # this is the list of all values that we want to select 
@@ -3347,7 +3358,7 @@ def _reorder_indexer(
33473358        """ 
33483359        # If the index is lexsorted and the list_like label in seq are sorted 
33493360        # then we do not need to sort 
3350-         if  self .is_lexsorted ():
3361+         if  self ._is_lexsorted ():
33513362            need_sort  =  False 
33523363            for  i , k  in  enumerate (seq ):
33533364                if  is_list_like (k ):
@@ -3768,6 +3779,15 @@ def isin(self, values, level=None):
37683779    __inv__  =  make_invalid_op ("__inv__" )
37693780
37703781
3782+ def  _lexsort_depth (codes : List [np .ndarray ], nlevels : int ) ->  int :
3783+     """Count depth (up to a maximum of `nlevels`) with which codes are lexsorted.""" 
3784+     int64_codes  =  [ensure_int64 (level_codes ) for  level_codes  in  codes ]
3785+     for  k  in  range (nlevels , 0 , - 1 ):
3786+         if  libalgos .is_lexsorted (int64_codes [:k ]):
3787+             return  k 
3788+     return  0 
3789+ 
3790+ 
37713791def  sparsify_labels (label_list , start : int  =  0 , sentinel = "" ):
37723792    pivoted  =  list (zip (* label_list ))
37733793    k  =  len (label_list )
0 commit comments