diff --git a/pandas/core/indexes/category.py b/pandas/core/indexes/category.py index 06df8f85cded7..d875cd682030b 100644 --- a/pandas/core/indexes/category.py +++ b/pandas/core/indexes/category.py @@ -529,19 +529,11 @@ def get_indexer(self, target, method=None, limit=None, tolerance=None): method = missing.clean_reindex_fill_method(method) target = ibase.ensure_index(target) + self._check_indexing_method(method) + if self.is_unique and self.equals(target): return np.arange(len(self), dtype="intp") - if method == "pad" or method == "backfill": - raise NotImplementedError( - "method='pad' and method='backfill' not " - "implemented yet for CategoricalIndex" - ) - elif method == "nearest": - raise NotImplementedError( - "method='nearest' not implemented yet for CategoricalIndex" - ) - # Note: we use engine.get_indexer_non_unique below because, even if # `target` is unique, any non-category entries in it will be encoded # as -1 by _get_codes_for_get_indexer, so `codes` may not be unique. diff --git a/pandas/core/indexes/extension.py b/pandas/core/indexes/extension.py index 4d09a97b18eed..c117c32f26d25 100644 --- a/pandas/core/indexes/extension.py +++ b/pandas/core/indexes/extension.py @@ -230,6 +230,21 @@ def __getitem__(self, key): # --------------------------------------------------------------------- + def _check_indexing_method(self, method): + """ + Raise if we have a get_indexer `method` that is not supported or valid. + """ + # GH#37871 for now this is only for IntervalIndex and CategoricalIndex + if method is None: + return + + if method in ["bfill", "backfill", "pad", "ffill", "nearest"]: + raise NotImplementedError( + f"method {method} not yet implemented for {type(self).__name__}" + ) + + raise ValueError("Invalid fill method") + def _get_engine_target(self) -> np.ndarray: return np.asarray(self._data) diff --git a/pandas/core/indexes/interval.py b/pandas/core/indexes/interval.py index 2aec86c9cdfae..e6174c63fbc15 100644 --- a/pandas/core/indexes/interval.py +++ b/pandas/core/indexes/interval.py @@ -582,17 +582,6 @@ def _maybe_convert_i8(self, key): return key_i8 - def _check_method(self, method): - if method is None: - return - - if method in ["bfill", "backfill", "pad", "ffill", "nearest"]: - raise NotImplementedError( - f"method {method} not yet implemented for IntervalIndex" - ) - - raise ValueError("Invalid fill method") - def _searchsorted_monotonic(self, label, side, exclude_label=False): if not self.is_non_overlapping_monotonic: raise KeyError( @@ -663,7 +652,7 @@ def get_loc( >>> index.get_loc(pd.Interval(0, 1)) 0 """ - self._check_method(method) + self._check_indexing_method(method) if not is_scalar(key): raise InvalidIndexError(key) @@ -714,7 +703,7 @@ def get_indexer( tolerance: Optional[Any] = None, ) -> np.ndarray: - self._check_method(method) + self._check_indexing_method(method) if self.is_overlapping: raise InvalidIndexError( diff --git a/pandas/tests/indexes/categorical/test_indexing.py b/pandas/tests/indexes/categorical/test_indexing.py index 9f4b7f7bad10f..cf9360821d37f 100644 --- a/pandas/tests/indexes/categorical/test_indexing.py +++ b/pandas/tests/indexes/categorical/test_indexing.py @@ -238,16 +238,14 @@ def test_get_indexer(self): r1 = idx1.get_indexer(idx2) tm.assert_almost_equal(r1, np.array([0, 1, 2, -1], dtype=np.intp)) - msg = ( - "method='pad' and method='backfill' not implemented yet for " - "CategoricalIndex" - ) + msg = "method pad not yet implemented for CategoricalIndex" with pytest.raises(NotImplementedError, match=msg): idx2.get_indexer(idx1, method="pad") + msg = "method backfill not yet implemented for CategoricalIndex" with pytest.raises(NotImplementedError, match=msg): idx2.get_indexer(idx1, method="backfill") - msg = "method='nearest' not implemented yet for CategoricalIndex" + msg = "method nearest not yet implemented for CategoricalIndex" with pytest.raises(NotImplementedError, match=msg): idx2.get_indexer(idx1, method="nearest")