Skip to content

Commit 6d5f8e5

Browse files
authored
REF: avoid _get_engine_target in _get_nearest_indexer (#43238)
1 parent 4bf7538 commit 6d5f8e5

File tree

1 file changed

+28
-12
lines changed

1 file changed

+28
-12
lines changed

pandas/core/indexes/base.py

+28-12
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,6 @@
163163
)
164164

165165
if TYPE_CHECKING:
166-
167166
from pandas import (
168167
CategoricalIndex,
169168
DataFrame,
@@ -172,6 +171,7 @@
172171
RangeIndex,
173172
Series,
174173
)
174+
from pandas.core.arrays import PeriodArray
175175

176176

177177
__all__ = ["Index"]
@@ -3701,19 +3701,18 @@ def _get_fill_indexer(
37013701
target=target._values, values=self._values, method=method, limit=limit
37023702
)
37033703

3704-
target_values = target._get_engine_target()
3705-
37063704
if self.is_monotonic_increasing and target.is_monotonic_increasing:
37073705
engine_method = (
37083706
self._engine.get_pad_indexer
37093707
if method == "pad"
37103708
else self._engine.get_backfill_indexer
37113709
)
3710+
target_values = target._get_engine_target()
37123711
indexer = engine_method(target_values, limit)
37133712
else:
37143713
indexer = self._get_fill_indexer_searchsorted(target, method, limit)
37153714
if tolerance is not None and len(self):
3716-
indexer = self._filter_indexer_tolerance(target_values, indexer, tolerance)
3715+
indexer = self._filter_indexer_tolerance(target, indexer, tolerance)
37173716
return indexer
37183717

37193718
@final
@@ -3765,10 +3764,8 @@ def _get_nearest_indexer(
37653764
left_indexer = self.get_indexer(target, "pad", limit=limit)
37663765
right_indexer = self.get_indexer(target, "backfill", limit=limit)
37673766

3768-
target_values = target._get_engine_target()
3769-
own_values = self._get_engine_target()
3770-
left_distances = np.abs(own_values[left_indexer] - target_values)
3771-
right_distances = np.abs(own_values[right_indexer] - target_values)
3767+
left_distances = self._difference_compat(target, left_indexer)
3768+
right_distances = self._difference_compat(target, right_indexer)
37723769

37733770
op = operator.lt if self.is_monotonic_increasing else operator.le
37743771
indexer = np.where(
@@ -3777,20 +3774,39 @@ def _get_nearest_indexer(
37773774
right_indexer,
37783775
)
37793776
if tolerance is not None:
3780-
indexer = self._filter_indexer_tolerance(target_values, indexer, tolerance)
3777+
indexer = self._filter_indexer_tolerance(target, indexer, tolerance)
37813778
return indexer
37823779

37833780
@final
37843781
def _filter_indexer_tolerance(
37853782
self,
3786-
target: np.ndarray,
3783+
target: Index,
37873784
indexer: npt.NDArray[np.intp],
37883785
tolerance,
37893786
) -> npt.NDArray[np.intp]:
3790-
own_values = self._get_engine_target()
3791-
distance = abs(own_values[indexer] - target)
3787+
3788+
distance = self._difference_compat(target, indexer)
3789+
37923790
return np.where(distance <= tolerance, indexer, -1)
37933791

3792+
@final
3793+
def _difference_compat(
3794+
self, target: Index, indexer: npt.NDArray[np.intp]
3795+
) -> ArrayLike:
3796+
# Compatibility for PeriodArray, for which __sub__ returns an ndarray[object]
3797+
# of DateOffset objects, which do not support __abs__ (and would be slow
3798+
# if they did)
3799+
3800+
if isinstance(self.dtype, PeriodDtype):
3801+
# Note: we only get here with matching dtypes
3802+
own_values = cast("PeriodArray", self._data)._ndarray
3803+
target_values = cast("PeriodArray", target._data)._ndarray
3804+
diff = own_values[indexer] - target_values
3805+
else:
3806+
# error: Unsupported left operand type for - ("ExtensionArray")
3807+
diff = self._values[indexer] - target._values # type: ignore[operator]
3808+
return abs(diff)
3809+
37943810
# --------------------------------------------------------------------
37953811
# Indexer Conversion Methods
37963812

0 commit comments

Comments
 (0)