|
30 | 30 | is_object_dtype,
|
31 | 31 | is_scalar,
|
32 | 32 | is_sequence,
|
33 |
| - needs_i8_conversion, |
34 | 33 | )
|
35 | 34 | from pandas.core.dtypes.concat import concat_compat
|
36 | 35 | from pandas.core.dtypes.generic import (
|
|
56 | 55 | length_of_indexer,
|
57 | 56 | )
|
58 | 57 | from pandas.core.indexes.api import (
|
59 |
| - CategoricalIndex, |
60 | 58 | Index,
|
61 |
| - IntervalIndex, |
62 | 59 | MultiIndex,
|
63 |
| - ensure_index, |
64 | 60 | )
|
65 | 61 |
|
66 | 62 | if TYPE_CHECKING:
|
@@ -1293,94 +1289,12 @@ def _get_listlike_indexer(self, key, axis: int):
|
1293 | 1289 | Indexer for the return object, -1 denotes keys not found.
|
1294 | 1290 | """
|
1295 | 1291 | ax = self.obj._get_axis(axis)
|
| 1292 | + axis_name = self.obj._get_axis_name(axis) |
1296 | 1293 |
|
1297 |
| - keyarr = key |
1298 |
| - if not isinstance(keyarr, Index): |
1299 |
| - keyarr = com.asarray_tuplesafe(keyarr) |
1300 |
| - |
1301 |
| - if isinstance(ax, MultiIndex): |
1302 |
| - # get_indexer expects a MultiIndex or sequence of tuples, but |
1303 |
| - # we may be doing partial-indexing, so need an extra check |
1304 |
| - |
1305 |
| - # Have the index compute an indexer or return None |
1306 |
| - # if it cannot handle: |
1307 |
| - indexer = ax._convert_listlike_indexer(keyarr) |
1308 |
| - # We only act on all found values: |
1309 |
| - if indexer is not None and (indexer != -1).all(): |
1310 |
| - # _validate_read_indexer is a no-op if no -1s, so skip |
1311 |
| - return ax[indexer], indexer |
1312 |
| - |
1313 |
| - if ax._index_as_unique: |
1314 |
| - indexer = ax.get_indexer_for(keyarr) |
1315 |
| - keyarr = ax.reindex(keyarr)[0] |
1316 |
| - else: |
1317 |
| - keyarr, indexer, new_indexer = ax._reindex_non_unique(keyarr) |
1318 |
| - |
1319 |
| - self._validate_read_indexer(keyarr, indexer, axis) |
1320 |
| - |
1321 |
| - if needs_i8_conversion(ax.dtype) or isinstance( |
1322 |
| - ax, (IntervalIndex, CategoricalIndex) |
1323 |
| - ): |
1324 |
| - # For CategoricalIndex take instead of reindex to preserve dtype. |
1325 |
| - # For IntervalIndex this is to map integers to the Intervals they match to. |
1326 |
| - keyarr = ax.take(indexer) |
1327 |
| - if keyarr.dtype.kind in ["m", "M"]: |
1328 |
| - # DTI/TDI.take can infer a freq in some cases when we dont want one |
1329 |
| - if isinstance(key, list) or ( |
1330 |
| - isinstance(key, type(ax)) and key.freq is None |
1331 |
| - ): |
1332 |
| - keyarr = keyarr._with_freq(None) |
| 1294 | + keyarr, indexer = ax._get_indexer_strict(key, axis_name) |
1333 | 1295 |
|
1334 | 1296 | return keyarr, indexer
|
1335 | 1297 |
|
1336 |
| - def _validate_read_indexer(self, key, indexer, axis: int): |
1337 |
| - """ |
1338 |
| - Check that indexer can be used to return a result. |
1339 |
| -
|
1340 |
| - e.g. at least one element was found, |
1341 |
| - unless the list of keys was actually empty. |
1342 |
| -
|
1343 |
| - Parameters |
1344 |
| - ---------- |
1345 |
| - key : list-like |
1346 |
| - Targeted labels (only used to show correct error message). |
1347 |
| - indexer: array-like of booleans |
1348 |
| - Indices corresponding to the key, |
1349 |
| - (with -1 indicating not found). |
1350 |
| - axis : int |
1351 |
| - Dimension on which the indexing is being made. |
1352 |
| -
|
1353 |
| - Raises |
1354 |
| - ------ |
1355 |
| - KeyError |
1356 |
| - If at least one key was requested but none was found. |
1357 |
| - """ |
1358 |
| - if len(key) == 0: |
1359 |
| - return |
1360 |
| - |
1361 |
| - # Count missing values: |
1362 |
| - missing_mask = indexer < 0 |
1363 |
| - missing = (missing_mask).sum() |
1364 |
| - |
1365 |
| - if missing: |
1366 |
| - ax = self.obj._get_axis(axis) |
1367 |
| - |
1368 |
| - # TODO: remove special-case; this is just to keep exception |
1369 |
| - # message tests from raising while debugging |
1370 |
| - use_interval_msg = isinstance(ax, IntervalIndex) or ( |
1371 |
| - isinstance(ax, CategoricalIndex) |
1372 |
| - and isinstance(ax.categories, IntervalIndex) |
1373 |
| - ) |
1374 |
| - |
1375 |
| - if missing == len(indexer): |
1376 |
| - axis_name = self.obj._get_axis_name(axis) |
1377 |
| - if use_interval_msg: |
1378 |
| - key = list(key) |
1379 |
| - raise KeyError(f"None of [{key}] are in the [{axis_name}]") |
1380 |
| - |
1381 |
| - not_found = list(ensure_index(key)[missing_mask.nonzero()[0]].unique()) |
1382 |
| - raise KeyError(f"{not_found} not in index") |
1383 |
| - |
1384 | 1298 |
|
1385 | 1299 | @doc(IndexingMixin.iloc)
|
1386 | 1300 | class _iLocIndexer(_LocationIndexer):
|
|
0 commit comments