From 12dafcf6ea8121557deba1f4c320351976cb6abb Mon Sep 17 00:00:00 2001 From: Fangchen Li Date: Sun, 6 Sep 2020 15:50:04 -0500 Subject: [PATCH 01/13] CLN: move sort_index to core/generic.py #8283 --- pandas/core/frame.py | 67 +++++------------------------- pandas/core/generic.py | 93 ++++++++++++++++++++++++++++++++++++++++++ pandas/core/series.py | 64 +++++------------------------ 3 files changed, 115 insertions(+), 109 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 150d6e24dbb86..3276e2bbc5a54 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -5466,62 +5466,17 @@ def sort_index( C 3 d 4 """ - # TODO: this can be combined with Series.sort_index impl as - # almost identical - - inplace = validate_bool_kwarg(inplace, "inplace") - - axis = self._get_axis_number(axis) - labels = self._get_axis(axis) - labels = ensure_key_mapped(labels, key, levels=level) - - # make sure that the axis is lexsorted to start - # if not we need to reconstruct to get the correct indexer - labels = labels._sort_levels_monotonic() - if level is not None: - new_axis, indexer = labels.sortlevel( - level, ascending=ascending, sort_remaining=sort_remaining - ) - - elif isinstance(labels, MultiIndex): - from pandas.core.sorting import lexsort_indexer - - indexer = lexsort_indexer( - labels._get_codes_for_sorting(), - orders=ascending, - na_position=na_position, - ) - else: - from pandas.core.sorting import nargsort - - # Check monotonic-ness before sort an index - # GH11080 - if (ascending and labels.is_monotonic_increasing) or ( - not ascending and labels.is_monotonic_decreasing - ): - if inplace: - return - else: - return self.copy() - - indexer = nargsort( - labels, kind=kind, ascending=ascending, na_position=na_position - ) - - baxis = self._get_block_manager_axis(axis) - new_data = self._mgr.take(indexer, axis=baxis, verify=False) - - # reconstruct axis if needed - new_data.axes[baxis] = new_data.axes[baxis]._sort_levels_monotonic() - - if ignore_index: - new_data.axes[1] = ibase.default_index(len(indexer)) - - result = self._constructor(new_data) - if inplace: - return self._update_inplace(result) - else: - return result.__finalize__(self, method="sort_index") + return super().sort_index( + axis, + level, + ascending, + inplace, + kind, + na_position, + sort_remaining, + ignore_index, + key, + ) def value_counts( self, diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 93c945638a174..6780ebf6ce24f 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -40,6 +40,7 @@ CompressionOptions, FilePathOrBuffer, FrameOrSeries, + IndexKeyFunc, JSONSerializable, Label, Level, @@ -68,6 +69,7 @@ from pandas.core.dtypes.common import ( ensure_int64, ensure_object, + ensure_platform_int, ensure_str, is_bool, is_bool_dtype, @@ -96,6 +98,7 @@ import pandas.core.common as com from pandas.core.construction import create_series_with_explicit_dtype from pandas.core.flags import Flags +from pandas.core.indexes import base as ibase from pandas.core.indexes.api import Index, MultiIndex, RangeIndex, ensure_index from pandas.core.indexes.datetimes import DatetimeIndex from pandas.core.indexes.period import Period, PeriodIndex @@ -104,6 +107,7 @@ from pandas.core.missing import find_valid_index from pandas.core.ops import _align_method_FRAME from pandas.core.shared_docs import _shared_docs +from pandas.core.sorting import ensure_key_mapped from pandas.core.window import Expanding, ExponentialMovingWindow, Rolling, Window from pandas.io.formats import format as fmt @@ -4418,6 +4422,95 @@ def sort_values( """ raise AbstractMethodError(self) + def sort_index( + self, + axis=0, + level=None, + ascending: bool_t = True, + inplace: bool_t = False, + kind: str = "quicksort", + na_position: str = "last", + sort_remaining: bool_t = True, + ignore_index: bool_t = False, + key: IndexKeyFunc = None, + ): + + inplace = validate_bool_kwarg(inplace, "inplace") + + is_dataframe = isinstance(self, ABCDataFrame) + if is_dataframe: + axis = self._get_axis_number(axis) + labels = self._get_axis(axis) + labels = ensure_key_mapped(labels, key, levels=level) + labels = labels._sort_levels_monotonic() + target = labels + else: + _ = self._get_axis_number(axis) + index = ensure_key_mapped(self.index, key, levels=level) + target = index + + if level is not None: + new_index, indexer = target.sortlevel( + level, ascending=ascending, sort_remaining=sort_remaining + ) + + elif isinstance(target, MultiIndex): + from pandas.core.sorting import lexsort_indexer + + if not is_dataframe: + target = target._sort_levels_monotonic() + + indexer = lexsort_indexer( + target._get_codes_for_sorting(), + orders=ascending, + na_position=na_position, + ) + + else: + from pandas.core.sorting import nargsort + + # Check monotonic-ness before sort an index + # GH11080 + if (ascending and target.is_monotonic_increasing) or ( + not ascending and target.is_monotonic_decreasing + ): + if inplace: + return + else: + return self.copy() + + indexer = nargsort( + target, kind=kind, ascending=ascending, na_position=na_position + ) + + if is_dataframe: + baxis = self._get_block_manager_axis(axis) + new_data = self._mgr.take(indexer, axis=baxis, verify=False) + + # reconstruct axis if needed + new_data.axes[baxis] = new_data.axes[baxis]._sort_levels_monotonic() + + if ignore_index: + new_data.axes[1] = ibase.default_index(len(indexer)) + + result = self._constructor(new_data) + + else: + indexer = ensure_platform_int(indexer) + new_index = self.index.take(indexer) + new_index = new_index._sort_levels_monotonic() + + new_values = self._values.take(indexer) + result = self._constructor(new_values, index=new_index) + + if ignore_index: + result.index = ibase.default_index(len(result)) + + if inplace: + return self._update_inplace(result) + else: + return result.__finalize__(self, method="sort_index") + @doc( klass=_shared_doc_kwargs["klass"], axes=_shared_doc_kwargs["axes"], diff --git a/pandas/core/series.py b/pandas/core/series.py index 6cbd93135a2ca..cfdf41ff4ce05 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -3462,59 +3462,17 @@ def sort_index( dtype: int64 """ - # TODO: this can be combined with DataFrame.sort_index impl as - # almost identical - inplace = validate_bool_kwarg(inplace, "inplace") - # Validate the axis parameter - self._get_axis_number(axis) - index = ensure_key_mapped(self.index, key, levels=level) - - if level is not None: - new_index, indexer = index.sortlevel( - level, ascending=ascending, sort_remaining=sort_remaining - ) - - elif isinstance(index, MultiIndex): - from pandas.core.sorting import lexsort_indexer - - labels = index._sort_levels_monotonic() - - indexer = lexsort_indexer( - labels._get_codes_for_sorting(), - orders=ascending, - na_position=na_position, - ) - else: - from pandas.core.sorting import nargsort - - # Check monotonic-ness before sort an index - # GH11080 - if (ascending and index.is_monotonic_increasing) or ( - not ascending and index.is_monotonic_decreasing - ): - if inplace: - return - else: - return self.copy() - - indexer = nargsort( - index, kind=kind, ascending=ascending, na_position=na_position - ) - - indexer = ensure_platform_int(indexer) - new_index = self.index.take(indexer) - new_index = new_index._sort_levels_monotonic() - - new_values = self._values.take(indexer) - result = self._constructor(new_values, index=new_index) - - if ignore_index: - result.index = ibase.default_index(len(result)) - - if inplace: - self._update_inplace(result) - else: - return result.__finalize__(self, method="sort_index") + return super().sort_index( + axis, + level, + ascending, + inplace, + kind, + na_position, + sort_remaining, + ignore_index, + key, + ) def argsort(self, axis=0, kind="quicksort", order=None) -> "Series": """ From c2e2cb31c8be23d97b94ef03bbcd0bf23dae461a Mon Sep 17 00:00:00 2001 From: Fangchen Li Date: Sun, 6 Sep 2020 18:56:13 -0500 Subject: [PATCH 02/13] CLN: ignore typing check in core/generic.py #8283 --- pandas/core/generic.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 6780ebf6ce24f..4f00671adfbf8 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -4461,7 +4461,7 @@ def sort_index( target = target._sort_levels_monotonic() indexer = lexsort_indexer( - target._get_codes_for_sorting(), + target._get_codes_for_sorting(), # type: ignore[attr-defined] orders=ascending, na_position=na_position, ) @@ -4501,7 +4501,9 @@ def sort_index( new_index = new_index._sort_levels_monotonic() new_values = self._values.take(indexer) - result = self._constructor(new_values, index=new_index) + result = self._constructor( + new_values, index=new_index # type: ignore[call-arg] + ) if ignore_index: result.index = ibase.default_index(len(result)) From 909fec647367605b943ae9fb9754c2ec79b5bd33 Mon Sep 17 00:00:00 2001 From: Fangchen Li Date: Sun, 6 Sep 2020 19:00:34 -0500 Subject: [PATCH 03/13] CLN: remove unused import #8283 --- pandas/core/frame.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index d3b40e5473c79..c61cfb68989a2 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -142,7 +142,6 @@ ) from pandas.core.reshape.melt import melt from pandas.core.series import Series -from pandas.core.sorting import ensure_key_mapped from pandas.io.common import get_filepath_or_buffer from pandas.io.formats import console, format as fmt From f0958b8fdac14c97b4f7038b08aa0105d9927e10 Mon Sep 17 00:00:00 2001 From: Fangchen Li Date: Mon, 7 Sep 2020 22:52:27 -0500 Subject: [PATCH 04/13] refactor --- pandas/core/generic.py | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 4f00671adfbf8..4cb2e064db4e2 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -4436,18 +4436,10 @@ def sort_index( ): inplace = validate_bool_kwarg(inplace, "inplace") - - is_dataframe = isinstance(self, ABCDataFrame) - if is_dataframe: - axis = self._get_axis_number(axis) - labels = self._get_axis(axis) - labels = ensure_key_mapped(labels, key, levels=level) - labels = labels._sort_levels_monotonic() - target = labels - else: - _ = self._get_axis_number(axis) - index = ensure_key_mapped(self.index, key, levels=level) - target = index + axis = self._get_axis_number(axis) + target = self._get_axis(axis) if isinstance(self, ABCDataFrame) else self.index + target = ensure_key_mapped(target, key, levels=level) + target = target._sort_levels_monotonic() if level is not None: new_index, indexer = target.sortlevel( @@ -4457,11 +4449,8 @@ def sort_index( elif isinstance(target, MultiIndex): from pandas.core.sorting import lexsort_indexer - if not is_dataframe: - target = target._sort_levels_monotonic() - indexer = lexsort_indexer( - target._get_codes_for_sorting(), # type: ignore[attr-defined] + target._get_codes_for_sorting(), orders=ascending, na_position=na_position, ) @@ -4483,7 +4472,7 @@ def sort_index( target, kind=kind, ascending=ascending, na_position=na_position ) - if is_dataframe: + if isinstance(self, ABCDataFrame): baxis = self._get_block_manager_axis(axis) new_data = self._mgr.take(indexer, axis=baxis, verify=False) From 3ebc89d0d09605704d520d26428a71c05c35dbf5 Mon Sep 17 00:00:00 2001 From: Fangchen Li Date: Tue, 8 Sep 2020 11:15:00 -0500 Subject: [PATCH 05/13] create function get indexer --- pandas/core/generic.py | 57 ++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 4cb2e064db4e2..217731f3462de 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -4422,30 +4422,16 @@ def sort_values( """ raise AbstractMethodError(self) - def sort_index( - self, - axis=0, - level=None, - ascending: bool_t = True, - inplace: bool_t = False, - kind: str = "quicksort", - na_position: str = "last", - sort_remaining: bool_t = True, - ignore_index: bool_t = False, - key: IndexKeyFunc = None, + def _get_indexer( + self, target, level, ascending, kind, na_position, sort_remaining, key ): - - inplace = validate_bool_kwarg(inplace, "inplace") - axis = self._get_axis_number(axis) - target = self._get_axis(axis) if isinstance(self, ABCDataFrame) else self.index target = ensure_key_mapped(target, key, levels=level) target = target._sort_levels_monotonic() if level is not None: - new_index, indexer = target.sortlevel( + _, indexer = target.sortlevel( level, ascending=ascending, sort_remaining=sort_remaining ) - elif isinstance(target, MultiIndex): from pandas.core.sorting import lexsort_indexer @@ -4454,23 +4440,46 @@ def sort_index( orders=ascending, na_position=na_position, ) - else: from pandas.core.sorting import nargsort - # Check monotonic-ness before sort an index - # GH11080 + # Check monotonic-ness before sort an index (GH 11080) if (ascending and target.is_monotonic_increasing) or ( not ascending and target.is_monotonic_decreasing ): - if inplace: - return - else: - return self.copy() + return None indexer = nargsort( target, kind=kind, ascending=ascending, na_position=na_position ) + return indexer + + def sort_index( + self, + axis=0, + level=None, + ascending: bool_t = True, + inplace: bool_t = False, + kind: str = "quicksort", + na_position: str = "last", + sort_remaining: bool_t = True, + ignore_index: bool_t = False, + key: IndexKeyFunc = None, + ): + + inplace = validate_bool_kwarg(inplace, "inplace") + axis = self._get_axis_number(axis) + target = self._get_axis(axis) + + indexer = self._get_indexer( + target, level, ascending, kind, na_position, sort_remaining, key + ) + + if indexer is None: + if inplace: + return + else: + return self.copy() if isinstance(self, ABCDataFrame): baxis = self._get_block_manager_axis(axis) From 8cb2fecc5e3d8f8c587f8f361553e266eecdc5fc Mon Sep 17 00:00:00 2001 From: Fangchen Li Date: Tue, 8 Sep 2020 20:27:32 -0500 Subject: [PATCH 06/13] move get_indexer to sorting --- pandas/core/generic.py | 36 ++---------------------------------- pandas/core/sorting.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 34 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 273123e7914d6..ccebc0aef63e1 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -107,7 +107,7 @@ from pandas.core.missing import find_valid_index from pandas.core.ops import align_method_FRAME from pandas.core.shared_docs import _shared_docs -from pandas.core.sorting import ensure_key_mapped +from pandas.core.sorting import ensure_key_mapped, get_indexer_indexer from pandas.core.window import Expanding, ExponentialMovingWindow, Rolling, Window from pandas.io.formats import format as fmt @@ -4422,38 +4422,6 @@ def sort_values( """ raise AbstractMethodError(self) - def _get_indexer( - self, target, level, ascending, kind, na_position, sort_remaining, key - ): - target = ensure_key_mapped(target, key, levels=level) - target = target._sort_levels_monotonic() - - if level is not None: - _, indexer = target.sortlevel( - level, ascending=ascending, sort_remaining=sort_remaining - ) - elif isinstance(target, MultiIndex): - from pandas.core.sorting import lexsort_indexer - - indexer = lexsort_indexer( - target._get_codes_for_sorting(), - orders=ascending, - na_position=na_position, - ) - else: - from pandas.core.sorting import nargsort - - # Check monotonic-ness before sort an index (GH 11080) - if (ascending and target.is_monotonic_increasing) or ( - not ascending and target.is_monotonic_decreasing - ): - return None - - indexer = nargsort( - target, kind=kind, ascending=ascending, na_position=na_position - ) - return indexer - def sort_index( self, axis=0, @@ -4471,7 +4439,7 @@ def sort_index( axis = self._get_axis_number(axis) target = self._get_axis(axis) - indexer = self._get_indexer( + indexer = get_indexer_indexer( target, level, ascending, kind, na_position, sort_remaining, key ) diff --git a/pandas/core/sorting.py b/pandas/core/sorting.py index d03b2f29521b7..7103655816295 100644 --- a/pandas/core/sorting.py +++ b/pandas/core/sorting.py @@ -25,6 +25,34 @@ _INT64_MAX = np.iinfo(np.int64).max +def get_indexer_indexer( + target, level, ascending, kind, na_position, sort_remaining, key +): + + target = ensure_key_mapped(target, key, levels=level) + target = target._sort_levels_monotonic() + + if level is not None: + _, indexer = target.sortlevel( + level, ascending=ascending, sort_remaining=sort_remaining + ) + elif isinstance(target, ABCMultiIndex): + indexer = lexsort_indexer( + target._get_codes_for_sorting(), orders=ascending, na_position=na_position, + ) + else: + # Check monotonic-ness before sort an index (GH 11080) + if (ascending and target.is_monotonic_increasing) or ( + not ascending and target.is_monotonic_decreasing + ): + return None + + indexer = nargsort( + target, kind=kind, ascending=ascending, na_position=na_position + ) + return indexer + + def get_group_index(labels, shape, sort: bool, xnull: bool): """ For the particular label_list, gets the offsets into the hypothetical list From a035fbd340897ea92f05dd58450feb3b1be33d44 Mon Sep 17 00:00:00 2001 From: Fangchen Li Date: Tue, 8 Sep 2020 20:45:51 -0500 Subject: [PATCH 07/13] remove unused import --- pandas/core/generic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index ccebc0aef63e1..3b3b218190f14 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -107,7 +107,7 @@ from pandas.core.missing import find_valid_index from pandas.core.ops import align_method_FRAME from pandas.core.shared_docs import _shared_docs -from pandas.core.sorting import ensure_key_mapped, get_indexer_indexer +from pandas.core.sorting import get_indexer_indexer from pandas.core.window import Expanding, ExponentialMovingWindow, Rolling, Window from pandas.io.formats import format as fmt From 9691439946dd8e6c6c7acbe3dd7a3f7cee3fea18 Mon Sep 17 00:00:00 2001 From: Fangchen Li Date: Wed, 9 Sep 2020 11:11:50 -0500 Subject: [PATCH 08/13] fix type import --- pandas/core/generic.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 17fd3d52fb891..b7bc3d9a11f62 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -40,6 +40,7 @@ CompressionOptions, FilePathOrBuffer, FrameOrSeries, + IndexKeyFunc, IndexLabel, JSONSerializable, Label, From c79cd8176ffb12eed6d90febaa43ed258a48cd4f Mon Sep 17 00:00:00 2001 From: Fangchen Li Date: Fri, 11 Sep 2020 13:28:51 -0500 Subject: [PATCH 09/13] simplify sort_index --- pandas/core/generic.py | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index b7bc3d9a11f62..9074cfc824daa 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -4450,30 +4450,17 @@ def sort_index( else: return self.copy() - if isinstance(self, ABCDataFrame): - baxis = self._get_block_manager_axis(axis) - new_data = self._mgr.take(indexer, axis=baxis, verify=False) - - # reconstruct axis if needed - new_data.axes[baxis] = new_data.axes[baxis]._sort_levels_monotonic() - - if ignore_index: - new_data.axes[1] = ibase.default_index(len(indexer)) - - result = self._constructor(new_data) + baxis = self._get_block_manager_axis(axis) + new_data = self._mgr.take(indexer, axis=baxis, verify=False) - else: - indexer = ensure_platform_int(indexer) - new_index = self.index.take(indexer) - new_index = new_index._sort_levels_monotonic() + # reconstruct axis if needed + new_data.axes[baxis] = new_data.axes[baxis]._sort_levels_monotonic() - new_values = self._values.take(indexer) - result = self._constructor( - new_values, index=new_index # type: ignore[call-arg] - ) + if ignore_index: + axis = 1 if isinstance(self, ABCDataFrame) else 0 + new_data.axes[axis] = ibase.default_index(len(indexer)) - if ignore_index: - result.index = ibase.default_index(len(result)) + result = self._constructor(new_data) if inplace: return self._update_inplace(result) From 8b9732a3eb33e6e580b872462c22f95bb30ff999 Mon Sep 17 00:00:00 2001 From: Fangchen Li Date: Fri, 11 Sep 2020 13:48:25 -0500 Subject: [PATCH 10/13] add doc string --- pandas/core/sorting.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pandas/core/sorting.py b/pandas/core/sorting.py index 7103655816295..0c315b52c2cb3 100644 --- a/pandas/core/sorting.py +++ b/pandas/core/sorting.py @@ -28,6 +28,24 @@ def get_indexer_indexer( target, level, ascending, kind, na_position, sort_remaining, key ): + """ + Helper method that return the indexer according to input parameters for + the sort_index method of DataFrame and Series. + + Parameters + ---------- + target : Index + level : int or level name or list of ints or list of level names + ascending : bool or list of bools, default True + kind : {'quicksort', 'mergesort', 'heapsort'}, default 'quicksort' + na_position : {'first', 'last'}, default 'last' + sort_remaining : bool, default True + key : callable, optional + Returns + ------- + Optional[ndarray] + The indexer for the new index. + """ target = ensure_key_mapped(target, key, levels=level) target = target._sort_levels_monotonic() From 4461b7bc0d1562011d2f48ab4b5592d347f585a1 Mon Sep 17 00:00:00 2001 From: Fangchen Li Date: Fri, 11 Sep 2020 14:14:10 -0500 Subject: [PATCH 11/13] remove unused import --- pandas/core/generic.py | 1 - pandas/core/sorting.py | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 9074cfc824daa..24eec022c0d26 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -70,7 +70,6 @@ from pandas.core.dtypes.common import ( ensure_int64, ensure_object, - ensure_platform_int, ensure_str, is_bool, is_bool_dtype, diff --git a/pandas/core/sorting.py b/pandas/core/sorting.py index 0c315b52c2cb3..c383d3a5db0fd 100644 --- a/pandas/core/sorting.py +++ b/pandas/core/sorting.py @@ -41,6 +41,7 @@ def get_indexer_indexer( na_position : {'first', 'last'}, default 'last' sort_remaining : bool, default True key : callable, optional + Returns ------- Optional[ndarray] From 15d7401f1255a2bebb8e1be48fb6cf7d32c9ab10 Mon Sep 17 00:00:00 2001 From: Fangchen Li Date: Sun, 13 Sep 2020 20:37:52 -0500 Subject: [PATCH 12/13] type get indexer --- pandas/core/sorting.py | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/pandas/core/sorting.py b/pandas/core/sorting.py index c383d3a5db0fd..e87f0a0e8865d 100644 --- a/pandas/core/sorting.py +++ b/pandas/core/sorting.py @@ -1,6 +1,15 @@ """ miscellaneous sorting / groupby utilities """ from collections import defaultdict -from typing import TYPE_CHECKING, Callable, DefaultDict, Iterable, List, Optional, Tuple +from typing import ( + TYPE_CHECKING, + Callable, + DefaultDict, + Iterable, + List, + Optional, + Tuple, + Union, +) import numpy as np @@ -20,14 +29,20 @@ from pandas.core.construction import extract_array if TYPE_CHECKING: - from pandas.core.indexes.base import Index # noqa:F401 + from pandas.core.indexes.base import Index _INT64_MAX = np.iinfo(np.int64).max def get_indexer_indexer( - target, level, ascending, kind, na_position, sort_remaining, key -): + target: "Index", + level: Union[str, int, List[str], List[int]], + ascending: bool, + kind: str, + na_position: str, + sort_remaining: bool, + key: Optional[Callable], +) -> Optional[np.array]: """ Helper method that return the indexer according to input parameters for the sort_index method of DataFrame and Series. From 58a62eeb723343c35b2545c188c493fa9cb7c652 Mon Sep 17 00:00:00 2001 From: Fangchen Li Date: Sun, 13 Sep 2020 20:48:51 -0500 Subject: [PATCH 13/13] fix type --- pandas/core/sorting.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/core/sorting.py b/pandas/core/sorting.py index e87f0a0e8865d..dd6aadf570baa 100644 --- a/pandas/core/sorting.py +++ b/pandas/core/sorting.py @@ -15,6 +15,7 @@ from pandas._libs import algos, hashtable, lib from pandas._libs.hashtable import unique_label_indices +from pandas._typing import IndexKeyFunc from pandas.core.dtypes.common import ( ensure_int64, @@ -41,7 +42,7 @@ def get_indexer_indexer( kind: str, na_position: str, sort_remaining: bool, - key: Optional[Callable], + key: IndexKeyFunc, ) -> Optional[np.array]: """ Helper method that return the indexer according to input parameters for