From 36756a6130158f5f816a39c6e60e09172742049a Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Tue, 4 Feb 2020 17:49:25 -0800 Subject: [PATCH 1/4] inline indexing 1liners --- pandas/core/indexing.py | 14 +++++--------- pandas/core/series.py | 7 ++----- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index acbf05a74d118..29dc8caefcd8d 100755 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -702,12 +702,6 @@ def _convert_tuple(self, key, setting: bool = False): keyidx.append(idx) return tuple(keyidx) - def _convert_scalar_indexer(self, key, axis: int): - # if we are accessing via lowered dim, use the last dim - ax = self.obj._get_axis(min(axis, self.ndim - 1)) - # a scalar - return ax._convert_scalar_indexer(key, kind=self.name) - def _convert_slice_indexer(self, key: slice, axis: int): # if we are accessing via lowered dim, use the last dim ax = self.obj._get_axis(min(axis, self.ndim - 1)) @@ -1627,7 +1621,8 @@ def _validate_key(self, key, axis: int): return if not is_list_like_indexer(key): - self._convert_scalar_indexer(key, axis) + labels = self.obj._get_axis(axis) + labels._convert_scalar_indexer(key, kind="loc") def _is_scalar_access(self, key: Tuple) -> bool: """ @@ -1801,7 +1796,7 @@ def _convert_to_indexer(self, key, axis: int, setting: bool = False): if is_scalar(key): # try to find out correct indexer, if not type correct raise try: - key = self._convert_scalar_indexer(key, axis) + key = labels._convert_scalar_indexer(key, kind="loc") except TypeError: # but we will allow setting if not setting: @@ -2046,7 +2041,8 @@ def _convert_to_indexer(self, key, axis: int, setting: bool = False): return self._convert_slice_indexer(key, axis) elif is_float(key): - return self._convert_scalar_indexer(key, axis) + labels = self.obj._get_axis(axis) + return labels._convert_scalar_indexer(key, kind="iloc") self._validate_key(key, axis) return key diff --git a/pandas/core/series.py b/pandas/core/series.py index 2ffb22d2d272f..5e29df3560761 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -852,6 +852,8 @@ def __getitem__(self, key): return self key_is_scalar = is_scalar(key) + if key_is_scalar: + key = self.index._convert_scalar_indexer(key, kind="getitem") if key_is_scalar or isinstance(self.index, MultiIndex): # Otherwise index.get_value will raise InvalidIndexError @@ -866,11 +868,6 @@ def __getitem__(self, key): # kludge pass else: - - # we can try to coerce the indexer (or this will raise) - new_key = self.index._convert_scalar_indexer(key, kind="getitem") - if type(new_key) != type(key): - return self.__getitem__(new_key) raise if not key_is_scalar: From 0464f7fd3c26c19517fb5de46537cab12994f1d1 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Tue, 4 Feb 2020 19:40:38 -0800 Subject: [PATCH 2/4] dont pass iloc to convert_scalar_indexer --- pandas/core/indexes/base.py | 2 +- pandas/core/indexes/datetimelike.py | 2 +- pandas/core/indexes/interval.py | 4 ++-- pandas/core/indexes/numeric.py | 14 +++++--------- pandas/core/indexing.py | 3 ++- 5 files changed, 11 insertions(+), 14 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 891ae95db65a0..40cf198fa78c5 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -3109,7 +3109,7 @@ def _convert_scalar_indexer(self, key, kind=None): key : label of the slice bound kind : {'loc', 'getitem', 'iloc'} or None """ - assert kind in ["loc", "getitem", "iloc", None] + assert kind in ["loc", "getitem", None] if kind == "iloc": self._validate_indexer("positional", key, "iloc") diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index 13fb955c32832..091de4ffa31de 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -396,7 +396,7 @@ def _convert_scalar_indexer(self, key, kind=None): kind : {'loc', 'getitem', 'iloc'} or None """ - assert kind in ["loc", "getitem", "iloc", None] + assert kind in ["loc", "getitem", None] if not is_scalar(key): raise TypeError(key) diff --git a/pandas/core/indexes/interval.py b/pandas/core/indexes/interval.py index 0252a13665b84..76acc619a69e3 100644 --- a/pandas/core/indexes/interval.py +++ b/pandas/core/indexes/interval.py @@ -529,8 +529,8 @@ def holds_integer(self): @Appender(Index._convert_scalar_indexer.__doc__) def _convert_scalar_indexer(self, key, kind=None): - if kind == "iloc": - return super()._convert_scalar_indexer(key, kind=kind) + assert kind in ["getitem", "loc", None] + # never iloc, so no-op return key def _maybe_cast_slice_bound(self, label, side, kind): diff --git a/pandas/core/indexes/numeric.py b/pandas/core/indexes/numeric.py index ebfe50327b479..006b0ae6f43f5 100644 --- a/pandas/core/indexes/numeric.py +++ b/pandas/core/indexes/numeric.py @@ -254,11 +254,10 @@ def asi8(self) -> np.ndarray: @Appender(Index._convert_scalar_indexer.__doc__) def _convert_scalar_indexer(self, key, kind=None): - assert kind in ["loc", "getitem", "iloc", None] + assert kind in ["loc", "getitem", None] - # don't coerce ilocs to integers - if kind != "iloc": - key = self._maybe_cast_indexer(key) + # never iloc, which we don't coerce to integers + key = self._maybe_cast_indexer(key) return super()._convert_scalar_indexer(key, kind=kind) @@ -385,11 +384,8 @@ def astype(self, dtype, copy=True): @Appender(Index._convert_scalar_indexer.__doc__) def _convert_scalar_indexer(self, key, kind=None): - assert kind in ["loc", "getitem", "iloc", None] - - if kind == "iloc": - self._validate_indexer("positional", key, "iloc") - + assert kind in ["loc", "getitem", None] + # no-op for non-iloc return key @Appender(Index._convert_slice_indexer.__doc__) diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 29dc8caefcd8d..8144eaa75cb21 100755 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -2042,7 +2042,8 @@ def _convert_to_indexer(self, key, axis: int, setting: bool = False): elif is_float(key): labels = self.obj._get_axis(axis) - return labels._convert_scalar_indexer(key, kind="iloc") + labels._validate_indexer("positional", key, "iloc") + return key self._validate_key(key, axis) return key From 17f08c46929e831aec908e2c1fda972ae80fb537 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Wed, 5 Feb 2020 08:36:32 -0800 Subject: [PATCH 3/4] CLN: _convert_scalar_indexer handle only loc and getitem --- pandas/core/indexes/base.py | 10 +++------- pandas/core/indexes/category.py | 5 +++-- pandas/core/indexes/datetimelike.py | 6 +++--- pandas/core/indexes/interval.py | 4 ++-- pandas/core/indexes/numeric.py | 8 ++++---- 5 files changed, 15 insertions(+), 18 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 40cf198fa78c5..c7fe071ab4299 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -3100,20 +3100,16 @@ def _filter_indexer_tolerance( # -------------------------------------------------------------------- # Indexer Conversion Methods - def _convert_scalar_indexer(self, key, kind=None): + def _convert_scalar_indexer(self, key, kind: str): """ Convert a scalar indexer. Parameters ---------- key : label of the slice bound - kind : {'loc', 'getitem', 'iloc'} or None + kind : {'loc', 'getitem'} """ - assert kind in ["loc", "getitem", None] - - if kind == "iloc": - self._validate_indexer("positional", key, "iloc") - return key + assert kind in ["loc", "getitem"] if len(self) and not isinstance(self, ABCMultiIndex): diff --git a/pandas/core/indexes/category.py b/pandas/core/indexes/category.py index 718b6afb70e06..6998907aa465d 100644 --- a/pandas/core/indexes/category.py +++ b/pandas/core/indexes/category.py @@ -658,10 +658,11 @@ def get_indexer_non_unique(self, target): return ensure_platform_int(indexer), missing @Appender(Index._convert_scalar_indexer.__doc__) - def _convert_scalar_indexer(self, key, kind=None): + def _convert_scalar_indexer(self, key, kind: str): + assert kind in ["loc", "getitem"] if kind == "loc": try: - return self.categories._convert_scalar_indexer(key, kind=kind) + return self.categories._convert_scalar_indexer(key, kind="loc") except TypeError: self._invalid_indexer("label", key) return super()._convert_scalar_indexer(key, kind=kind) diff --git a/pandas/core/indexes/datetimelike.py b/pandas/core/indexes/datetimelike.py index 091de4ffa31de..b143ff0aa9c02 100644 --- a/pandas/core/indexes/datetimelike.py +++ b/pandas/core/indexes/datetimelike.py @@ -385,7 +385,7 @@ def _format_attrs(self): # -------------------------------------------------------------------- # Indexing Methods - def _convert_scalar_indexer(self, key, kind=None): + def _convert_scalar_indexer(self, key, kind: str): """ We don't allow integer or float indexing on datetime-like when using loc. @@ -393,10 +393,10 @@ def _convert_scalar_indexer(self, key, kind=None): Parameters ---------- key : label of the slice bound - kind : {'loc', 'getitem', 'iloc'} or None + kind : {'loc', 'getitem'} """ - assert kind in ["loc", "getitem", None] + assert kind in ["loc", "getitem"] if not is_scalar(key): raise TypeError(key) diff --git a/pandas/core/indexes/interval.py b/pandas/core/indexes/interval.py index 76acc619a69e3..48de79a5f106c 100644 --- a/pandas/core/indexes/interval.py +++ b/pandas/core/indexes/interval.py @@ -528,8 +528,8 @@ def holds_integer(self): # TODO: There must already exist something for this? @Appender(Index._convert_scalar_indexer.__doc__) - def _convert_scalar_indexer(self, key, kind=None): - assert kind in ["getitem", "loc", None] + def _convert_scalar_indexer(self, key, kind: str): + assert kind in ["getitem", "loc"] # never iloc, so no-op return key diff --git a/pandas/core/indexes/numeric.py b/pandas/core/indexes/numeric.py index 006b0ae6f43f5..271ec52eb8e3a 100644 --- a/pandas/core/indexes/numeric.py +++ b/pandas/core/indexes/numeric.py @@ -253,8 +253,8 @@ def asi8(self) -> np.ndarray: return self.values.view(self._default_dtype) @Appender(Index._convert_scalar_indexer.__doc__) - def _convert_scalar_indexer(self, key, kind=None): - assert kind in ["loc", "getitem", None] + def _convert_scalar_indexer(self, key, kind: str): + assert kind in ["loc", "getitem"] # never iloc, which we don't coerce to integers key = self._maybe_cast_indexer(key) @@ -383,8 +383,8 @@ def astype(self, dtype, copy=True): return super().astype(dtype, copy=copy) @Appender(Index._convert_scalar_indexer.__doc__) - def _convert_scalar_indexer(self, key, kind=None): - assert kind in ["loc", "getitem", None] + def _convert_scalar_indexer(self, key, kind: str): + assert kind in ["loc", "getitem"] # no-op for non-iloc return key From d1135dcbc11a7a9fe4e6717f8995d680d541f638 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Wed, 5 Feb 2020 09:44:56 -0800 Subject: [PATCH 4/4] mypy fixup --- pandas/core/indexes/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index c7fe071ab4299..f070b157429cd 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -3100,7 +3100,7 @@ def _filter_indexer_tolerance( # -------------------------------------------------------------------- # Indexer Conversion Methods - def _convert_scalar_indexer(self, key, kind: str): + def _convert_scalar_indexer(self, key, kind: str_t): """ Convert a scalar indexer.