Skip to content

Commit f7f03f3

Browse files
authored
REF: remove unnecessary PeriodIndex._get_indexer (#39685)
1 parent 80431ad commit f7f03f3

File tree

6 files changed

+30
-55
lines changed

6 files changed

+30
-55
lines changed

pandas/core/indexes/base.py

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3398,7 +3398,7 @@ def _get_fill_indexer(
33983398
else:
33993399
indexer = self._get_fill_indexer_searchsorted(target, method, limit)
34003400
if tolerance is not None and len(self):
3401-
indexer = self._filter_indexer_tolerance(target._values, indexer, tolerance)
3401+
indexer = self._filter_indexer_tolerance(target_values, indexer, tolerance)
34023402
return indexer
34033403

34043404
@final
@@ -3448,15 +3448,10 @@ def _get_nearest_indexer(self, target: Index, limit, tolerance) -> np.ndarray:
34483448
left_indexer = self.get_indexer(target, "pad", limit=limit)
34493449
right_indexer = self.get_indexer(target, "backfill", limit=limit)
34503450

3451-
target_values = target._values
3452-
# error: Unsupported left operand type for - ("ExtensionArray")
3453-
left_distances = np.abs(
3454-
self._values[left_indexer] - target_values # type: ignore[operator]
3455-
)
3456-
# error: Unsupported left operand type for - ("ExtensionArray")
3457-
right_distances = np.abs(
3458-
self._values[right_indexer] - target_values # type: ignore[operator]
3459-
)
3451+
target_values = target._get_engine_target()
3452+
own_values = self._get_engine_target()
3453+
left_distances = np.abs(own_values[left_indexer] - target_values)
3454+
right_distances = np.abs(own_values[right_indexer] - target_values)
34603455

34613456
op = operator.lt if self.is_monotonic_increasing else operator.le
34623457
indexer = np.where(
@@ -3475,8 +3470,8 @@ def _filter_indexer_tolerance(
34753470
indexer: np.ndarray,
34763471
tolerance,
34773472
) -> np.ndarray:
3478-
# error: Unsupported left operand type for - ("ExtensionArray")
3479-
distance = abs(self._values[indexer] - target) # type: ignore[operator]
3473+
own_values = self._get_engine_target()
3474+
distance = abs(own_values[indexer] - target)
34803475
return np.where(distance <= tolerance, indexer, -1)
34813476

34823477
# --------------------------------------------------------------------

pandas/core/indexes/datetimelike.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -231,10 +231,7 @@ def take(self, indices, axis=0, allow_fill=True, fill_value=None, **kwargs):
231231

232232
def _convert_tolerance(self, tolerance, target):
233233
tolerance = np.asarray(to_timedelta(tolerance).to_numpy())
234-
235-
if target.size != tolerance.size and tolerance.size > 1:
236-
raise ValueError("list-like tolerance size must match target index size")
237-
return tolerance
234+
return super()._convert_tolerance(tolerance, target)
238235

239236
def tolist(self) -> List:
240237
"""

pandas/core/indexes/numeric.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,8 @@ def _shallow_copy(self, values, name: Hashable = lib.no_default):
119119
return super()._shallow_copy(values=values, name=name)
120120

121121
def _convert_tolerance(self, tolerance, target):
122-
tolerance = np.asarray(tolerance)
123-
if target.size != tolerance.size and tolerance.size > 1:
124-
raise ValueError("list-like tolerance size must match target index size")
122+
tolerance = super()._convert_tolerance(tolerance, target)
123+
125124
if not np.issubdtype(tolerance.dtype, np.number):
126125
if tolerance.ndim > 0:
127126
raise ValueError(

pandas/core/indexes/period.py

Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from pandas._libs.tslibs.parsing import DateParseError, parse_time_string
1212
from pandas._typing import Dtype, DtypeObj
1313
from pandas.errors import InvalidIndexError
14-
from pandas.util._decorators import cache_readonly, doc
14+
from pandas.util._decorators import doc
1515

1616
from pandas.core.dtypes.common import (
1717
is_bool_dtype,
@@ -324,10 +324,6 @@ def __contains__(self, key: Any) -> bool:
324324
except KeyError:
325325
return False
326326

327-
@cache_readonly
328-
def _int64index(self) -> Int64Index:
329-
return Int64Index._simple_new(self.asi8, name=self.name)
330-
331327
# ------------------------------------------------------------------------
332328
# Index Methods
333329

@@ -424,24 +420,18 @@ def inferred_type(self) -> str:
424420
# ------------------------------------------------------------------------
425421
# Indexing Methods
426422

427-
def _get_indexer(self, target: Index, method=None, limit=None, tolerance=None):
428-
429-
if not self._should_compare(target):
430-
return self._get_indexer_non_comparable(target, method, unique=True)
431-
432-
if isinstance(target, PeriodIndex):
433-
target = target._int64index # i.e. target.asi8
434-
self_index = self._int64index
435-
else:
436-
self_index = self
423+
def _convert_tolerance(self, tolerance, target):
424+
# Returned tolerance must be in dtype/units so that
425+
# `|self._get_engine_target() - target._engine_target()| <= tolerance`
426+
# is meaningful. Since PeriodIndex returns int64 for engine_target,
427+
# we may need to convert timedelta64 tolerance to int64.
428+
tolerance = super()._convert_tolerance(tolerance, target)
437429

438-
if tolerance is not None:
439-
tolerance = self._convert_tolerance(tolerance, target)
440-
if self_index is not self:
441-
# convert tolerance to i8
442-
tolerance = self._maybe_convert_timedelta(tolerance)
430+
if self.dtype == target.dtype:
431+
# convert tolerance to i8
432+
tolerance = self._maybe_convert_timedelta(tolerance)
443433

444-
return Index._get_indexer(self_index, target, method, limit, tolerance)
434+
return tolerance
445435

446436
def get_loc(self, key, method=None, tolerance=None):
447437
"""
@@ -579,14 +569,6 @@ def _get_string_slice(self, key: str):
579569
except KeyError as err:
580570
raise KeyError(key) from err
581571

582-
# ------------------------------------------------------------------------
583-
584-
def memory_usage(self, deep: bool = False) -> int:
585-
result = super().memory_usage(deep=deep)
586-
if hasattr(self, "_cache") and "_int64index" in self._cache:
587-
result += self._int64index.memory_usage(deep=deep)
588-
return result
589-
590572

591573
def period_range(
592574
start=None, end=None, periods: Optional[int] = None, freq=None, name=None

pandas/core/indexes/range.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from datetime import timedelta
44
import operator
55
from sys import getsizeof
6-
from typing import Any, Hashable, List, Optional, Tuple
6+
from typing import TYPE_CHECKING, Any, Hashable, List, Optional, Tuple
77
import warnings
88

99
import numpy as np
@@ -20,7 +20,6 @@
2020
ensure_python_int,
2121
is_float,
2222
is_integer,
23-
is_list_like,
2423
is_scalar,
2524
is_signed_integer_dtype,
2625
is_timedelta64_dtype,
@@ -35,6 +34,9 @@
3534
from pandas.core.indexes.numeric import Float64Index, Int64Index
3635
from pandas.core.ops.common import unpack_zerodim_and_defer
3736

37+
if TYPE_CHECKING:
38+
from pandas import Index
39+
3840
_empty_range = range(0)
3941

4042

@@ -368,8 +370,8 @@ def get_loc(self, key, method=None, tolerance=None):
368370
raise KeyError(key)
369371
return super().get_loc(key, method=method, tolerance=tolerance)
370372

371-
def _get_indexer(self, target, method=None, limit=None, tolerance=None):
372-
if com.any_not_none(method, tolerance, limit) or not is_list_like(target):
373+
def _get_indexer(self, target: Index, method=None, limit=None, tolerance=None):
374+
if com.any_not_none(method, tolerance, limit):
373375
return super()._get_indexer(
374376
target, method=method, tolerance=tolerance, limit=limit
375377
)
@@ -381,11 +383,11 @@ def _get_indexer(self, target, method=None, limit=None, tolerance=None):
381383
reverse = self._range[::-1]
382384
start, stop, step = reverse.start, reverse.stop, reverse.step
383385

384-
target_array = np.asarray(target)
385-
if not (is_signed_integer_dtype(target_array) and target_array.ndim == 1):
386+
if not is_signed_integer_dtype(target):
386387
# checks/conversions/roundings are delegated to general method
387388
return super()._get_indexer(target, method=method, tolerance=tolerance)
388389

390+
target_array = np.asarray(target)
389391
locs = target_array - start
390392
valid = (locs % step == 0) & (locs >= 0) & (target_array < stop)
391393
locs[~valid] = -1

pandas/tests/indexes/period/test_constructors.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ def test_constructor_simple_new(self):
329329
msg = "Should be numpy array of type i8"
330330
with pytest.raises(AssertionError, match=msg):
331331
# Need ndarray, not Int64Index
332-
type(idx._data)._simple_new(idx._int64index, freq=idx.freq)
332+
type(idx._data)._simple_new(Index(idx.asi8), freq=idx.freq)
333333

334334
arr = type(idx._data)._simple_new(idx.asi8, freq=idx.freq)
335335
result = idx._simple_new(arr, name="p")

0 commit comments

Comments
 (0)