diff --git a/pandas/_libs/lib.pyi b/pandas/_libs/lib.pyi index 2439082bf7413..72b46d9e30684 100644 --- a/pandas/_libs/lib.pyi +++ b/pandas/_libs/lib.pyi @@ -240,6 +240,6 @@ def get_reverse_indexer( ) -> npt.NDArray[np.intp]: ... def is_bool_list(obj: list) -> bool: ... def dtypes_all_equal(types: list[DtypeObj]) -> bool: ... -def array_equal_fast( - left: np.ndarray, right: np.ndarray # np.ndarray[np.int64, ndim=1] +def is_range_indexer( + left: np.ndarray, n: int # np.ndarray[np.int64, ndim=1] ) -> bool: ... diff --git a/pandas/_libs/lib.pyx b/pandas/_libs/lib.pyx index 176307ef27cff..16d5bbaad9de9 100644 --- a/pandas/_libs/lib.pyx +++ b/pandas/_libs/lib.pyx @@ -650,22 +650,20 @@ ctypedef fused int6432_t: @cython.wraparound(False) @cython.boundscheck(False) -def array_equal_fast( - ndarray[int6432_t, ndim=1] left, ndarray[int6432_t, ndim=1] right, -) -> bool: +def is_range_indexer(ndarray[int6432_t, ndim=1] left, int n) -> bool: """ Perform an element by element comparison on 1-d integer arrays, meant for indexer comparisons """ cdef: - Py_ssize_t i, n = left.size + Py_ssize_t i - if left.size != right.size: + if left.size != n: return False for i in range(n): - if left[i] != right[i]: + if left[i] != i: return False return True diff --git a/pandas/core/frame.py b/pandas/core/frame.py index eb0eb34dbefc4..3b122eaa814e5 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -48,7 +48,7 @@ from pandas._libs.hashtable import duplicated from pandas._libs.lib import ( NoDefault, - array_equal_fast, + is_range_indexer, no_default, ) from pandas._typing import ( @@ -6724,7 +6724,7 @@ def sort_values( else: return self.copy(deep=None) - if array_equal_fast(indexer, np.arange(0, len(indexer), dtype=indexer.dtype)): + if is_range_indexer(indexer, len(indexer)): if inplace: return self._update_inplace(self) else: diff --git a/pandas/core/generic.py b/pandas/core/generic.py index ab9b76fbdf712..a91c46d7d06c4 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -35,7 +35,7 @@ ) from pandas._libs import lib -from pandas._libs.lib import array_equal_fast +from pandas._libs.lib import is_range_indexer from pandas._libs.tslibs import ( Period, Tick, @@ -3780,10 +3780,7 @@ def _take( axis == 0 and indices.ndim == 1 and using_copy_on_write() - and array_equal_fast( - indices, - np.arange(0, len(self), dtype=np.intp), - ) + and is_range_indexer(indices, len(self)) ): return self.copy(deep=None) diff --git a/pandas/core/series.py b/pandas/core/series.py index 91f7095e59db5..2849b009cf72c 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -33,7 +33,7 @@ reshape, ) from pandas._libs.lib import ( - array_equal_fast, + is_range_indexer, no_default, ) from pandas._typing import ( @@ -891,7 +891,7 @@ def take(self, indices, axis: Axis = 0, **kwargs) -> Series: if ( indices.ndim == 1 and using_copy_on_write() - and array_equal_fast(indices, np.arange(0, len(self), dtype=indices.dtype)) + and is_range_indexer(indices, len(self)) ): return self.copy(deep=None) @@ -3566,9 +3566,7 @@ def sort_values( values_to_sort = ensure_key_mapped(self, key)._values if key else self._values sorted_index = nargsort(values_to_sort, kind, bool(ascending), na_position) - if array_equal_fast( - sorted_index, np.arange(0, len(sorted_index), dtype=sorted_index.dtype) - ): + if is_range_indexer(sorted_index, len(sorted_index)): if inplace: return self._update_inplace(self) return self.copy(deep=None) diff --git a/pandas/tests/libs/test_lib.py b/pandas/tests/libs/test_lib.py index e352250dc748d..302dc21ec997c 100644 --- a/pandas/tests/libs/test_lib.py +++ b/pandas/tests/libs/test_lib.py @@ -244,25 +244,22 @@ def test_get_reverse_indexer(self): tm.assert_numpy_array_equal(result, expected) @pytest.mark.parametrize("dtype", ["int64", "int32"]) - def test_array_equal_fast(self, dtype): + def test_is_range_indexer(self, dtype): # GH#50592 - left = np.arange(1, 100, dtype=dtype) - right = np.arange(1, 100, dtype=dtype) - assert lib.array_equal_fast(left, right) + left = np.arange(0, 100, dtype=dtype) + assert lib.is_range_indexer(left, 100) @pytest.mark.parametrize("dtype", ["int64", "int32"]) - def test_array_equal_fast_not_equal(self, dtype): + def test_is_range_indexer_not_equal(self, dtype): # GH#50592 left = np.array([1, 2], dtype=dtype) - right = np.array([2, 2], dtype=dtype) - assert not lib.array_equal_fast(left, right) + assert not lib.is_range_indexer(left, 2) @pytest.mark.parametrize("dtype", ["int64", "int32"]) - def test_array_equal_fast_not_equal_shape(self, dtype): + def test_is_range_indexer_not_equal_shape(self, dtype): # GH#50592 - left = np.array([1, 2, 3], dtype=dtype) - right = np.array([2, 2], dtype=dtype) - assert not lib.array_equal_fast(left, right) + left = np.array([0, 1, 2], dtype=dtype) + assert not lib.is_range_indexer(left, 2) def test_cache_readonly_preserve_docstrings():