Skip to content

Commit bbcbb10

Browse files
jbrockmendelJulianWgs
authored andcommitted
REF: remove Index._convert_list_indexer (pandas-dev#41804)
1 parent d53dfd8 commit bbcbb10

File tree

7 files changed

+28
-52
lines changed

7 files changed

+28
-52
lines changed

pandas/core/indexes/base.py

+1-17
Original file line numberDiff line numberDiff line change
@@ -3720,7 +3720,7 @@ def _convert_listlike_indexer(self, keyarr):
37203720
else:
37213721
keyarr = self._convert_arr_indexer(keyarr)
37223722

3723-
indexer = self._convert_list_indexer(keyarr)
3723+
indexer = None
37243724
return indexer, keyarr
37253725

37263726
def _convert_arr_indexer(self, keyarr) -> np.ndarray:
@@ -3738,22 +3738,6 @@ def _convert_arr_indexer(self, keyarr) -> np.ndarray:
37383738
"""
37393739
return com.asarray_tuplesafe(keyarr)
37403740

3741-
def _convert_list_indexer(self, keyarr):
3742-
"""
3743-
Convert a list-like indexer to the appropriate dtype.
3744-
3745-
Parameters
3746-
----------
3747-
keyarr : Index (or sub-class)
3748-
Indexer to convert.
3749-
kind : iloc, loc, optional
3750-
3751-
Returns
3752-
-------
3753-
positional indexer or None
3754-
"""
3755-
return None
3756-
37573741
@final
37583742
def _invalid_indexer(self, form: str_t, key) -> TypeError:
37593743
"""

pandas/core/indexes/category.py

-12
Original file line numberDiff line numberDiff line change
@@ -525,18 +525,6 @@ def _get_indexer_non_unique(
525525
indexer, missing = self._engine.get_indexer_non_unique(codes)
526526
return ensure_platform_int(indexer), ensure_platform_int(missing)
527527

528-
@doc(Index._convert_list_indexer)
529-
def _convert_list_indexer(self, keyarr):
530-
# Return our indexer or raise if all of the values are not included in
531-
# the categories
532-
533-
if self.categories._defer_to_indexing:
534-
# See tests.indexing.interval.test_interval:test_loc_getitem_frame
535-
indexer = self.categories._convert_list_indexer(keyarr)
536-
return Index(self.codes).get_indexer_for(indexer)
537-
538-
return self.get_indexer_for(keyarr)
539-
540528
# --------------------------------------------------------------------
541529

542530
def _is_comparable_dtype(self, dtype: DtypeObj) -> bool:

pandas/core/indexes/interval.py

-14
Original file line numberDiff line numberDiff line change
@@ -815,20 +815,6 @@ def _maybe_cast_slice_bound(self, label, side: str, kind=lib.no_default):
815815
self._deprecated_arg(kind, "kind", "_maybe_cast_slice_bound")
816816
return getattr(self, side)._maybe_cast_slice_bound(label, side)
817817

818-
@Appender(Index._convert_list_indexer.__doc__)
819-
def _convert_list_indexer(self, keyarr):
820-
"""
821-
we are passed a list-like indexer. Return the
822-
indexer for matching intervals.
823-
"""
824-
locs = self.get_indexer_for(keyarr)
825-
826-
# we have missing values
827-
if (locs == -1).any():
828-
raise KeyError(keyarr[locs == -1].tolist())
829-
830-
return locs
831-
832818
def _is_comparable_dtype(self, dtype: DtypeObj) -> bool:
833819
if not isinstance(dtype, IntervalDtype):
834820
return False

pandas/core/indexing.py

+20-3
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,11 @@
5151
length_of_indexer,
5252
)
5353
from pandas.core.indexes.api import (
54+
CategoricalIndex,
5455
Index,
56+
IntervalIndex,
5557
MultiIndex,
58+
ensure_index,
5659
)
5760

5861
if TYPE_CHECKING:
@@ -1297,6 +1300,11 @@ def _get_listlike_indexer(self, key, axis: int):
12971300
keyarr, indexer, new_indexer = ax._reindex_non_unique(keyarr)
12981301

12991302
self._validate_read_indexer(keyarr, indexer, axis)
1303+
1304+
if isinstance(ax, (IntervalIndex, CategoricalIndex)):
1305+
# take instead of reindex to preserve dtype. For IntervalIndex
1306+
# this is to map integers to the Intervals they match to.
1307+
keyarr = ax.take(indexer)
13001308
return keyarr, indexer
13011309

13021310
def _validate_read_indexer(self, key, indexer, axis: int):
@@ -1329,13 +1337,22 @@ def _validate_read_indexer(self, key, indexer, axis: int):
13291337
missing = (missing_mask).sum()
13301338

13311339
if missing:
1340+
ax = self.obj._get_axis(axis)
1341+
1342+
# TODO: remove special-case; this is just to keep exception
1343+
# message tests from raising while debugging
1344+
use_interval_msg = isinstance(ax, IntervalIndex) or (
1345+
isinstance(ax, CategoricalIndex)
1346+
and isinstance(ax.categories, IntervalIndex)
1347+
)
1348+
13321349
if missing == len(indexer):
13331350
axis_name = self.obj._get_axis_name(axis)
1351+
if use_interval_msg:
1352+
key = list(key)
13341353
raise KeyError(f"None of [{key}] are in the [{axis_name}]")
13351354

1336-
ax = self.obj._get_axis(axis)
1337-
1338-
not_found = list(set(key) - set(ax))
1355+
not_found = list(ensure_index(key)[missing_mask.nonzero()[0]].unique())
13391356
raise KeyError(f"{not_found} not in index")
13401357

13411358

pandas/tests/indexing/interval/test_interval.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,10 @@ def test_getitem_non_matching(self, series_with_interval_index, indexer_sl):
6565

6666
# this is a departure from our current
6767
# indexing scheme, but simpler
68-
with pytest.raises(KeyError, match=r"^\[-1\]$"):
68+
with pytest.raises(KeyError, match=r"\[-1\] not in index"):
6969
indexer_sl(ser)[[-1, 3, 4, 5]]
7070

71-
with pytest.raises(KeyError, match=r"^\[-1\]$"):
71+
with pytest.raises(KeyError, match=r"\[-1\] not in index"):
7272
indexer_sl(ser)[[-1, 3]]
7373

7474
@pytest.mark.slow
@@ -107,11 +107,11 @@ def test_loc_getitem_frame(self):
107107
expected = df.take([4, 5, 4, 5])
108108
tm.assert_frame_equal(result, expected)
109109

110-
with pytest.raises(KeyError, match=r"^\[10\]$"):
110+
with pytest.raises(KeyError, match=r"None of \[\[10\]\] are"):
111111
df.loc[[10]]
112112

113113
# partial missing
114-
with pytest.raises(KeyError, match=r"^\[10\]$"):
114+
with pytest.raises(KeyError, match=r"\[10\] not in index"):
115115
df.loc[[10, 4]]
116116

117117

pandas/tests/indexing/interval/test_interval_new.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,8 @@ def test_loc_with_overlap(self, indexer_sl):
150150
with pytest.raises(KeyError, match=re.escape("Interval(3, 5, closed='right')")):
151151
indexer_sl(ser)[Interval(3, 5)]
152152

153-
with pytest.raises(KeyError, match=r"^\[Interval\(3, 5, closed='right'\)\]$"):
153+
msg = r"None of \[\[Interval\(3, 5, closed='right'\)\]\]"
154+
with pytest.raises(KeyError, match=msg):
154155
indexer_sl(ser)[[Interval(3, 5)]]
155156

156157
# slices with interval (only exact matches)

pandas/tests/indexing/test_indexing.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ def test_multitype_list_index_access(self):
338338
# GH 10610
339339
df = DataFrame(np.random.random((10, 5)), columns=["a"] + [20, 21, 22, 23])
340340

341-
with pytest.raises(KeyError, match=re.escape("'[-8, 26] not in index'")):
341+
with pytest.raises(KeyError, match=re.escape("'[26, -8] not in index'")):
342342
df[[22, 26, -8]]
343343
assert df[21].shape[0] == df.shape[0]
344344

0 commit comments

Comments
 (0)