From 95a7bd603afcbfa563dbbecacdcec0d1fbbef439 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Tue, 28 Jan 2020 11:24:43 -0800 Subject: [PATCH] PERF: avoid is_bool_indexer check where possible --- pandas/core/series.py | 49 ++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/pandas/core/series.py b/pandas/core/series.py index 0aaa583885bc3..33d4460c5f930 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -856,31 +856,36 @@ def __getitem__(self, key): if key is Ellipsis: return self - try: - result = self.index.get_value(self, key) + key_is_scalar = is_scalar(key) - return result - except InvalidIndexError: - pass - except (KeyError, ValueError): - if isinstance(key, tuple) and isinstance(self.index, MultiIndex): - # kludge - pass - elif com.is_bool_indexer(key): + if key_is_scalar or isinstance(self.index, MultiIndex): + # Otherwise index.get_value will raise InvalidIndexError + try: + result = self.index.get_value(self, key) + + return result + except InvalidIndexError: pass - else: + except (KeyError, ValueError): + if isinstance(key, tuple) and isinstance(self.index, MultiIndex): + # 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 + # 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 is_iterator(key): - key = list(key) + if not key_is_scalar: + # avoid expensive checks if we know we have a scalar + if is_iterator(key): + key = list(key) - if com.is_bool_indexer(key): - key = check_bool_indexer(self.index, key) + if com.is_bool_indexer(key): + key = check_bool_indexer(self.index, key) + return self._get_values(key) return self._get_with(key) @@ -913,6 +918,8 @@ def _get_with(self, key): else: key_type = lib.infer_dtype(key, skipna=False) + # Note: The key_type == "boolean" case should be caught by the + # com.is_bool_indexer check in __getitem__ if key_type == "integer": if self.index.is_integer() or self.index.is_floating(): return self.loc[key] @@ -921,8 +928,6 @@ def _get_with(self, key): return self.iloc[indexer] else: return self._get_values(key) - elif key_type == "boolean": - return self._get_values(key) if isinstance(key, (list, tuple)): # TODO: de-dup with tuple case handled above?