Skip to content

TYP: Index get_indexer_foo methods #31137

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 2 commits into from
Jan 19, 2020
Merged
Show file tree
Hide file tree
Changes from all 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
22 changes: 10 additions & 12 deletions pandas/_libs/index.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,8 @@ cdef class IndexEngine:
return self.monotonic_dec == 1

cdef inline _do_monotonic_check(self):
cdef object is_unique
cdef:
bint is_unique
try:
values = self._get_index_values()
self.monotonic_inc, self.monotonic_dec, is_unique = \
Expand All @@ -236,10 +237,10 @@ cdef class IndexEngine:
cdef _call_monotonic(self, values):
return algos.is_monotonic(values, timelike=False)

def get_backfill_indexer(self, other, limit=None):
def get_backfill_indexer(self, other: np.ndarray, limit=None) -> np.ndarray:
return algos.backfill(self._get_index_values(), other, limit=limit)

def get_pad_indexer(self, other, limit=None):
def get_pad_indexer(self, other: np.ndarray, limit=None) -> np.ndarray:
return algos.pad(self._get_index_values(), other, limit=limit)

cdef _make_hash_table(self, Py_ssize_t n):
Expand Down Expand Up @@ -477,13 +478,13 @@ cdef class DatetimeEngine(Int64Engine):
values = np.asarray(values).view('i8')
return self.mapping.lookup(values)

def get_pad_indexer(self, other, limit=None):
def get_pad_indexer(self, other: np.ndarray, limit=None) -> np.ndarray:
if other.dtype != self._get_box_dtype():
return np.repeat(-1, len(other)).astype('i4')
other = np.asarray(other).view('i8')
return algos.pad(self._get_index_values(), other, limit=limit)

def get_backfill_indexer(self, other, limit=None):
def get_backfill_indexer(self, other: np.ndarray, limit=None) -> np.ndarray:
if other.dtype != self._get_box_dtype():
return np.repeat(-1, len(other)).astype('i4')
other = np.asarray(other).view('i8')
Expand All @@ -506,16 +507,13 @@ cdef class PeriodEngine(Int64Engine):
cdef _get_index_values(self):
return super(PeriodEngine, self).vgetter().view("i8")

cdef void _call_map_locations(self, values):
# super(...) pattern doesn't seem to work with `cdef`
Int64Engine._call_map_locations(self, values.view('i8'))

cdef _call_monotonic(self, values):
# super(...) pattern doesn't seem to work with `cdef`
return Int64Engine._call_monotonic(self, values.view('i8'))

def get_indexer(self, values):
cdef ndarray[int64_t, ndim=1] ordinals
cdef:
ndarray[int64_t, ndim=1] ordinals

super(PeriodEngine, self)._ensure_mapping_populated()

Expand All @@ -524,14 +522,14 @@ cdef class PeriodEngine(Int64Engine):

return self.mapping.lookup(ordinals)

def get_pad_indexer(self, other, limit=None):
def get_pad_indexer(self, other: np.ndarray, limit=None) -> np.ndarray:
freq = super(PeriodEngine, self).vgetter().freq
ordinal = periodlib.extract_ordinals(other, freq)

return algos.pad(self._get_index_values(),
np.asarray(ordinal), limit=limit)

def get_backfill_indexer(self, other, limit=None):
def get_backfill_indexer(self, other: np.ndarray, limit=None) -> np.ndarray:
freq = super(PeriodEngine, self).vgetter().freq
ordinal = periodlib.extract_ordinals(other, freq)

Expand Down
5 changes: 1 addition & 4 deletions pandas/_libs/index_class_helper.pxi.in
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,7 @@ cdef class {{name}}Engine(IndexEngine):
ndarray[{{ctype}}] values
int count = 0

{{if name not in {'Float64', 'Float32'} }}
if not util.is_integer_object(val):
raise KeyError(val)
{{endif}}
self._check_type(val)

# A view is needed for some subclasses, such as PeriodEngine:
values = self._get_index_values().view('{{dtype}}')
Expand Down
23 changes: 16 additions & 7 deletions pandas/core/indexes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
duplicated="np.ndarray",
)
_index_shared_docs = dict()
str_t = str


def _make_comparison_op(op, cls):
Expand Down Expand Up @@ -2959,7 +2960,9 @@ def get_loc(self, key, method=None, tolerance=None):
"""

@Appender(_index_shared_docs["get_indexer"] % _index_doc_kwargs)
def get_indexer(self, target, method=None, limit=None, tolerance=None):
def get_indexer(
self, target, method=None, limit=None, tolerance=None
) -> np.ndarray:
method = missing.clean_reindex_fill_method(method)
target = ensure_index(target)
if tolerance is not None:
Expand Down Expand Up @@ -3016,14 +3019,16 @@ def _convert_tolerance(self, tolerance, target):
raise ValueError("list-like tolerance size must match target index size")
return tolerance

def _get_fill_indexer(self, target, method, limit=None, tolerance=None):
def _get_fill_indexer(
self, target: "Index", method: str_t, limit=None, tolerance=None
) -> np.ndarray:
if self.is_monotonic_increasing and target.is_monotonic_increasing:
method = (
engine_method = (
self._engine.get_pad_indexer
if method == "pad"
else self._engine.get_backfill_indexer
)
indexer = method(target._ndarray_values, limit)
indexer = engine_method(target._ndarray_values, limit)
else:
indexer = self._get_fill_indexer_searchsorted(target, method, limit)
if tolerance is not None:
Expand All @@ -3032,7 +3037,9 @@ def _get_fill_indexer(self, target, method, limit=None, tolerance=None):
)
return indexer

def _get_fill_indexer_searchsorted(self, target, method, limit=None):
def _get_fill_indexer_searchsorted(
self, target: "Index", method: str_t, limit=None
) -> np.ndarray:
"""
Fallback pad/backfill get_indexer that works for monotonic decreasing
indexes and non-monotonic targets.
Expand Down Expand Up @@ -3063,7 +3070,7 @@ def _get_fill_indexer_searchsorted(self, target, method, limit=None):
indexer[indexer == len(self)] = -1
return indexer

def _get_nearest_indexer(self, target, limit, tolerance):
def _get_nearest_indexer(self, target: "Index", limit, tolerance) -> np.ndarray:
"""
Get the indexer for the nearest index labels; requires an index with
values that can be subtracted from each other (e.g., not strings or
Expand All @@ -3086,7 +3093,9 @@ def _get_nearest_indexer(self, target, limit, tolerance):
indexer = self._filter_indexer_tolerance(target, indexer, tolerance)
return indexer

def _filter_indexer_tolerance(self, target, indexer, tolerance):
def _filter_indexer_tolerance(
self, target: "Index", indexer: np.ndarray, tolerance
) -> np.ndarray:
distance = abs(self.values[indexer] - target)
indexer = np.where(distance <= tolerance, indexer, -1)
return indexer
Expand Down