|
13 | 13 |
|
14 | 14 | from pandas.core.dtypes import concat as _concat
|
15 | 15 | from pandas.core.dtypes.common import (
|
16 |
| - ensure_python_int, is_int64_dtype, is_integer, is_scalar, |
17 |
| - is_timedelta64_dtype) |
| 16 | + ensure_platform_int, ensure_python_int, is_int64_dtype, is_integer, |
| 17 | + is_integer_dtype, is_list_like, is_scalar, is_timedelta64_dtype) |
18 | 18 | from pandas.core.dtypes.generic import (
|
19 | 19 | ABCDataFrame, ABCSeries, ABCTimedeltaIndex)
|
20 | 20 |
|
@@ -348,6 +348,36 @@ def get_loc(self, key, method=None, tolerance=None):
|
348 | 348 | raise KeyError(key)
|
349 | 349 | return super().get_loc(key, method=method, tolerance=tolerance)
|
350 | 350 |
|
| 351 | + @Appender(_index_shared_docs['get_indexer']) |
| 352 | + def get_indexer(self, target, method=None, limit=None, tolerance=None): |
| 353 | + if not (method is None and tolerance is None and is_list_like(target)): |
| 354 | + return super().get_indexer(target, method=method, |
| 355 | + tolerance=tolerance) |
| 356 | + |
| 357 | + if self.step > 0: |
| 358 | + start, stop, step = self.start, self.stop, self.step |
| 359 | + else: |
| 360 | + # Work on reversed range for simplicity: |
| 361 | + start, stop, step = (self.stop - self.step, |
| 362 | + self.start + 1, |
| 363 | + - self.step) |
| 364 | + |
| 365 | + target_array = np.asarray(target) |
| 366 | + if not (is_integer_dtype(target_array) and target_array.ndim == 1): |
| 367 | + # checks/conversions/roundings are delegated to general method |
| 368 | + return super().get_indexer(target, method=method, |
| 369 | + tolerance=tolerance) |
| 370 | + |
| 371 | + locs = target_array - start |
| 372 | + valid = (locs % step == 0) & (locs >= 0) & (target_array < stop) |
| 373 | + locs[~valid] = -1 |
| 374 | + locs[valid] = locs[valid] / step |
| 375 | + |
| 376 | + if step != self.step: |
| 377 | + # We reversed this range: transform to original locs |
| 378 | + locs[valid] = len(self) - 1 - locs[valid] |
| 379 | + return ensure_platform_int(locs) |
| 380 | + |
351 | 381 | def tolist(self):
|
352 | 382 | return list(self._range)
|
353 | 383 |
|
|
0 commit comments