@@ -99,8 +99,9 @@ def get_indexer_indexer(
9999 na_position = na_position ,
100100 )
101101 elif isinstance (target , ABCMultiIndex ):
102+ codes = [lev .codes for lev in target ._get_codes_for_sorting ()]
102103 indexer = lexsort_indexer (
103- target . codes , orders = ascending , na_position = na_position , codes_given = True
104+ codes , orders = ascending , na_position = na_position , codes_given = True
104105 )
105106 else :
106107 # Check monotonic-ness before sort an index (GH 11080)
@@ -298,22 +299,8 @@ def decons_obs_group_ids(
298299 return [lab [indexer ].astype (np .intp , subok = False , copy = True ) for lab in labels ]
299300
300301
301- def indexer_from_factorized (
302- labels , shape : Shape , compress : bool = True
303- ) -> npt .NDArray [np .intp ]:
304- ids = get_group_index (labels , shape , sort = True , xnull = False )
305-
306- if not compress :
307- ngroups = (ids .size and ids .max ()) + 1
308- else :
309- ids , obs = compress_group_index (ids , sort = True )
310- ngroups = len (obs )
311-
312- return get_group_index_sorter (ids , ngroups )
313-
314-
315302def lexsort_indexer (
316- keys : list [ArrayLike ] | list [ Series ],
303+ keys : Sequence [ArrayLike | Index | Series ],
317304 orders = None ,
318305 na_position : str = "last" ,
319306 key : Callable | None = None ,
@@ -324,9 +311,9 @@ def lexsort_indexer(
324311
325312 Parameters
326313 ----------
327- keys : list [ArrayLike] | list[ Series]
328- Sequence of ndarrays to be sorted by the indexer
329- list [Series] is only if key is not None.
314+ keys : Sequence [ArrayLike | Index | Series]
315+ Sequence of arrays to be sorted by the indexer
316+ Sequence [Series] is only if key is not None.
330317 orders : bool or list of booleans, optional
331318 Determines the sorting order for each element in keys. If a list,
332319 it must be the same length as keys. This determines whether the
@@ -346,83 +333,38 @@ def lexsort_indexer(
346333 """
347334 from pandas .core .arrays import Categorical
348335
349- labels = []
350- shape = []
336+ if na_position not in ["last" , "first" ]:
337+ raise ValueError (f"invalid na_position: { na_position } " )
338+
351339 if isinstance (orders , bool ):
352340 orders = [orders ] * len (keys )
353341 elif orders is None :
354342 orders = [True ] * len (keys )
355343
356- # error: Incompatible types in assignment (expression has type
357- # "List[Union[ExtensionArray, ndarray[Any, Any], Index, Series]]", variable
358- # has type "Union[List[Union[ExtensionArray, ndarray[Any, Any]]], List[Series]]")
359- keys = [ensure_key_mapped (k , key ) for k in keys ] # type: ignore[assignment]
344+ labels = []
360345
361346 for k , order in zip (keys , orders ):
362- if na_position not in ["last" , "first" ]:
363- raise ValueError (f"invalid na_position: { na_position } " )
364-
347+ k = ensure_key_mapped (k , key )
365348 if codes_given :
366- mask = k == - 1
367- codes = k .copy ()
368- n = len (codes )
369- mask_n = n
370- # error: Item "ExtensionArray" of "Union[Any, ExtensionArray,
371- # ndarray[Any, Any]]" has no attribute "any"
372- if mask .any (): # type: ignore[union-attr]
373- n -= 1
374-
349+ codes = cast (np .ndarray , k )
350+ n = codes .max () + 1 if len (codes ) else 0
375351 else :
376352 cat = Categorical (k , ordered = True )
353+ codes = cat .codes
377354 n = len (cat .categories )
378- codes = cat .codes .copy ()
379- mask = cat .codes == - 1
380- if mask .any ():
381- mask_n = n + 1
382- else :
383- mask_n = n
384-
385- if order : # ascending
386- if na_position == "last" :
387- # error: Argument 1 to "where" has incompatible type "Union[Any,
388- # ExtensionArray, ndarray[Any, Any]]"; expected
389- # "Union[_SupportsArray[dtype[Any]],
390- # _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float,
391- # complex, str, bytes, _NestedSequence[Union[bool, int, float,
392- # complex, str, bytes]]]"
393- codes = np .where (mask , n , codes ) # type: ignore[arg-type]
394- elif na_position == "first" :
395- # error: Incompatible types in assignment (expression has type
396- # "Union[Any, int, ndarray[Any, dtype[signedinteger[Any]]]]",
397- # variable has type "Union[Series, ExtensionArray, ndarray[Any, Any]]")
398- # error: Unsupported operand types for + ("ExtensionArray" and "int")
399- codes += 1 # type: ignore[operator,assignment]
400- else : # not order means descending
401- if na_position == "last" :
402- # error: Unsupported operand types for - ("int" and "ExtensionArray")
403- # error: Argument 1 to "where" has incompatible type "Union[Any,
404- # ExtensionArray, ndarray[Any, Any]]"; expected
405- # "Union[_SupportsArray[dtype[Any]],
406- # _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float,
407- # complex, str, bytes, _NestedSequence[Union[bool, int, float,
408- # complex, str, bytes]]]"
409- codes = np .where (
410- mask , n , n - codes - 1 # type: ignore[operator,arg-type]
411- )
412- elif na_position == "first" :
413- # error: Unsupported operand types for - ("int" and "ExtensionArray")
414- # error: Argument 1 to "where" has incompatible type "Union[Any,
415- # ExtensionArray, ndarray[Any, Any]]"; expected
416- # "Union[_SupportsArray[dtype[Any]],
417- # _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float,
418- # complex, str, bytes, _NestedSequence[Union[bool, int, float,
419- # complex, str, bytes]]]"
420- codes = np .where (mask , 0 , n - codes ) # type: ignore[operator,arg-type]
421-
422- shape .append (mask_n )
355+
356+ mask = codes == - 1
357+
358+ if na_position == "last" and mask .any ():
359+ codes = np .where (mask , n , codes )
360+
361+ # not order means descending
362+ if not order :
363+ codes = np .where (mask , codes , n - codes - 1 )
364+
423365 labels .append (codes )
424366
425- return indexer_from_factorized (labels , tuple ( shape ) )
367+ return np . lexsort (labels [:: - 1 ] )
426368
427369
428370def nargsort (
0 commit comments