163
163
)
164
164
165
165
if TYPE_CHECKING :
166
-
167
166
from pandas import (
168
167
CategoricalIndex ,
169
168
DataFrame ,
172
171
RangeIndex ,
173
172
Series ,
174
173
)
174
+ from pandas .core .arrays import PeriodArray
175
175
176
176
177
177
__all__ = ["Index" ]
@@ -3701,19 +3701,18 @@ def _get_fill_indexer(
3701
3701
target = target ._values , values = self ._values , method = method , limit = limit
3702
3702
)
3703
3703
3704
- target_values = target ._get_engine_target ()
3705
-
3706
3704
if self .is_monotonic_increasing and target .is_monotonic_increasing :
3707
3705
engine_method = (
3708
3706
self ._engine .get_pad_indexer
3709
3707
if method == "pad"
3710
3708
else self ._engine .get_backfill_indexer
3711
3709
)
3710
+ target_values = target ._get_engine_target ()
3712
3711
indexer = engine_method (target_values , limit )
3713
3712
else :
3714
3713
indexer = self ._get_fill_indexer_searchsorted (target , method , limit )
3715
3714
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 )
3717
3716
return indexer
3718
3717
3719
3718
@final
@@ -3765,10 +3764,8 @@ def _get_nearest_indexer(
3765
3764
left_indexer = self .get_indexer (target , "pad" , limit = limit )
3766
3765
right_indexer = self .get_indexer (target , "backfill" , limit = limit )
3767
3766
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 )
3772
3769
3773
3770
op = operator .lt if self .is_monotonic_increasing else operator .le
3774
3771
indexer = np .where (
@@ -3777,20 +3774,39 @@ def _get_nearest_indexer(
3777
3774
right_indexer ,
3778
3775
)
3779
3776
if tolerance is not None :
3780
- indexer = self ._filter_indexer_tolerance (target_values , indexer , tolerance )
3777
+ indexer = self ._filter_indexer_tolerance (target , indexer , tolerance )
3781
3778
return indexer
3782
3779
3783
3780
@final
3784
3781
def _filter_indexer_tolerance (
3785
3782
self ,
3786
- target : np . ndarray ,
3783
+ target : Index ,
3787
3784
indexer : npt .NDArray [np .intp ],
3788
3785
tolerance ,
3789
3786
) -> 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
+
3792
3790
return np .where (distance <= tolerance , indexer , - 1 )
3793
3791
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
+
3794
3810
# --------------------------------------------------------------------
3795
3811
# Indexer Conversion Methods
3796
3812
0 commit comments