Skip to content

REF: remove unnecessary PeriodIndex._get_indexer #39685

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 8, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 7 additions & 12 deletions pandas/core/indexes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3384,7 +3384,7 @@ def _get_fill_indexer(
else:
indexer = self._get_fill_indexer_searchsorted(target, method, limit)
if tolerance is not None and len(self):
indexer = self._filter_indexer_tolerance(target._values, indexer, tolerance)
indexer = self._filter_indexer_tolerance(target_values, indexer, tolerance)
return indexer

@final
Expand Down Expand Up @@ -3434,15 +3434,10 @@ def _get_nearest_indexer(self, target: Index, limit, tolerance) -> np.ndarray:
left_indexer = self.get_indexer(target, "pad", limit=limit)
right_indexer = self.get_indexer(target, "backfill", limit=limit)

target_values = target._values
# error: Unsupported left operand type for - ("ExtensionArray")
left_distances = np.abs(
self._values[left_indexer] - target_values # type: ignore[operator]
)
# error: Unsupported left operand type for - ("ExtensionArray")
right_distances = np.abs(
self._values[right_indexer] - target_values # type: ignore[operator]
)
target_values = target._get_engine_target()
own_values = self._get_engine_target()
left_distances = np.abs(own_values[left_indexer] - target_values)
right_distances = np.abs(own_values[right_indexer] - target_values)

op = operator.lt if self.is_monotonic_increasing else operator.le
indexer = np.where(
Expand All @@ -3461,8 +3456,8 @@ def _filter_indexer_tolerance(
indexer: np.ndarray,
tolerance,
) -> np.ndarray:
# error: Unsupported left operand type for - ("ExtensionArray")
distance = abs(self._values[indexer] - target) # type: ignore[operator]
own_values = self._get_engine_target()
distance = abs(own_values[indexer] - target)
return np.where(distance <= tolerance, indexer, -1)

# --------------------------------------------------------------------
Expand Down
4 changes: 1 addition & 3 deletions pandas/core/indexes/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,8 @@ def take(self, indices, axis=0, allow_fill=True, fill_value=None, **kwargs):
"""The expected NA value to use with this index."""

def _convert_tolerance(self, tolerance, target):
tolerance = super()._convert_tolerance(tolerance, target)
tolerance = np.asarray(to_timedelta(tolerance).to_numpy())

if target.size != tolerance.size and tolerance.size > 1:
raise ValueError("list-like tolerance size must match target index size")
return tolerance

def tolist(self) -> List:
Expand Down
5 changes: 2 additions & 3 deletions pandas/core/indexes/numeric.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,8 @@ def _shallow_copy(self, values=None, name: Hashable = lib.no_default):
return super()._shallow_copy(values=values, name=name)

def _convert_tolerance(self, tolerance, target):
tolerance = np.asarray(tolerance)
if target.size != tolerance.size and tolerance.size > 1:
raise ValueError("list-like tolerance size must match target index size")
tolerance = super()._convert_tolerance(tolerance, target)

if not np.issubdtype(tolerance.dtype, np.number):
if tolerance.ndim > 0:
raise ValueError(
Expand Down
40 changes: 11 additions & 29 deletions pandas/core/indexes/period.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from pandas._libs.tslibs.parsing import DateParseError, parse_time_string
from pandas._typing import Dtype, DtypeObj
from pandas.errors import InvalidIndexError
from pandas.util._decorators import cache_readonly, doc
from pandas.util._decorators import doc

from pandas.core.dtypes.common import (
is_bool_dtype,
Expand Down Expand Up @@ -324,10 +324,6 @@ def __contains__(self, key: Any) -> bool:
except KeyError:
return False

@cache_readonly
def _int64index(self) -> Int64Index:
return Int64Index._simple_new(self.asi8, name=self.name)

# ------------------------------------------------------------------------
# Index Methods

Expand Down Expand Up @@ -424,24 +420,18 @@ def inferred_type(self) -> str:
# ------------------------------------------------------------------------
# Indexing Methods

def _get_indexer(self, target: Index, method=None, limit=None, tolerance=None):

if not self._should_compare(target):
return self._get_indexer_non_comparable(target, method, unique=True)

if isinstance(target, PeriodIndex):
target = target._int64index # i.e. target.asi8
self_index = self._int64index
else:
self_index = self
def _convert_tolerance(self, tolerance, target):
# Returned tolerance must be in dtype/units so that
# `|self._get_engine_target() - target._engine_target()| <= tolerance`
# is meaningful. Since PeriodIndex returns int64 for engine_target,
# we may need to convert timedelta64 tolerance to int64.
tolerance = super()._convert_tolerance(tolerance, target)

if tolerance is not None:
tolerance = self._convert_tolerance(tolerance, target)
if self_index is not self:
# convert tolerance to i8
tolerance = self._maybe_convert_timedelta(tolerance)
if self.dtype == target.dtype:
# convert tolerance to i8
tolerance = self._maybe_convert_timedelta(tolerance)

return Index._get_indexer(self_index, target, method, limit, tolerance)
return tolerance

def get_loc(self, key, method=None, tolerance=None):
"""
Expand Down Expand Up @@ -579,14 +569,6 @@ def _get_string_slice(self, key: str):
except KeyError as err:
raise KeyError(key) from err

# ------------------------------------------------------------------------

def memory_usage(self, deep: bool = False) -> int:
result = super().memory_usage(deep=deep)
if hasattr(self, "_cache") and "_int64index" in self._cache:
result += self._int64index.memory_usage(deep=deep)
return result


def period_range(
start=None, end=None, periods: Optional[int] = None, freq=None, name=None
Expand Down
14 changes: 8 additions & 6 deletions pandas/core/indexes/range.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from datetime import timedelta
import operator
from sys import getsizeof
from typing import Any, Hashable, List, Optional, Tuple
from typing import TYPE_CHECKING, Any, Hashable, List, Optional, Tuple
import warnings

import numpy as np
Expand All @@ -20,7 +20,6 @@
ensure_python_int,
is_float,
is_integer,
is_list_like,
is_scalar,
is_signed_integer_dtype,
is_timedelta64_dtype,
Expand All @@ -35,6 +34,9 @@
from pandas.core.indexes.numeric import Float64Index, Int64Index
from pandas.core.ops.common import unpack_zerodim_and_defer

if TYPE_CHECKING:
from pandas import Index

_empty_range = range(0)


Expand Down Expand Up @@ -368,8 +370,8 @@ def get_loc(self, key, method=None, tolerance=None):
raise KeyError(key)
return super().get_loc(key, method=method, tolerance=tolerance)

def _get_indexer(self, target, method=None, limit=None, tolerance=None):
if com.any_not_none(method, tolerance, limit) or not is_list_like(target):
def _get_indexer(self, target: Index, method=None, limit=None, tolerance=None):
if com.any_not_none(method, tolerance, limit):
return super()._get_indexer(
target, method=method, tolerance=tolerance, limit=limit
)
Expand All @@ -381,11 +383,11 @@ def _get_indexer(self, target, method=None, limit=None, tolerance=None):
reverse = self._range[::-1]
start, stop, step = reverse.start, reverse.stop, reverse.step

target_array = np.asarray(target)
if not (is_signed_integer_dtype(target_array) and target_array.ndim == 1):
if not is_signed_integer_dtype(target):
# checks/conversions/roundings are delegated to general method
return super()._get_indexer(target, method=method, tolerance=tolerance)

target_array = np.asarray(target)
locs = target_array - start
valid = (locs % step == 0) & (locs >= 0) & (target_array < stop)
locs[~valid] = -1
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/indexes/period/test_constructors.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ def test_constructor_simple_new(self):
msg = "Should be numpy array of type i8"
with pytest.raises(AssertionError, match=msg):
# Need ndarray, not Int64Index
type(idx._data)._simple_new(idx._int64index, freq=idx.freq)
type(idx._data)._simple_new(Index(idx.asi8), freq=idx.freq)

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