From 45c11c61df9cb2644f2b60d3969b7c9d97e2bacb Mon Sep 17 00:00:00 2001 From: Brock Date: Fri, 24 Mar 2023 16:02:30 -0700 Subject: [PATCH] REF/TYP: stricter typing for Series._slice --- pandas/core/frame.py | 12 ++---------- pandas/core/generic.py | 21 ++++++++++++++++++++- pandas/core/series.py | 11 +++++------ 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index bef7022a7d10f..f1a1f842d2107 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -3758,18 +3758,10 @@ def __getitem__(self, key): elif is_mi and self.columns.is_unique and key in self.columns: return self._getitem_multilevel(key) + # Do we have a slicer (on rows)? if isinstance(key, slice): - indexer = self.index._convert_slice_indexer(key, kind="getitem") - if isinstance(indexer, np.ndarray): - # reachable with DatetimeIndex - indexer = lib.maybe_indices_to_slice( - indexer.astype(np.intp, copy=False), len(self) - ) - if isinstance(indexer, np.ndarray): - # GH#43223 If we can not convert, use take - return self.take(indexer, axis=0) - return self._slice(indexer, axis=0) + return self._getitem_slice(key) # Do we have a (boolean) DataFrame? if isinstance(key, DataFrame): diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 2b650d99c7e6c..141fababb15be 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -4141,7 +4141,26 @@ class animal locomotion def __getitem__(self, item): raise AbstractMethodError(self) - def _slice(self, slobj: slice, axis: Axis = 0) -> Self: + @final + def _getitem_slice(self, key: slice) -> Self: + """ + __getitem__ for the case where the key is a slice object. + """ + # _convert_slice_indexer to determine if this slice is positional + # or label based, and if the latter, convert to positional + slobj = self.index._convert_slice_indexer(key, kind="getitem") + if isinstance(slobj, np.ndarray): + # reachable with DatetimeIndex + indexer = lib.maybe_indices_to_slice( + slobj.astype(np.intp, copy=False), len(self) + ) + if isinstance(indexer, np.ndarray): + # GH#43223 If we can not convert, use take + return self.take(indexer, axis=0) + slobj = indexer + return self._slice(slobj) + + def _slice(self, slobj: slice, axis: AxisInt = 0) -> Self: """ Construct a slice of this container. diff --git a/pandas/core/series.py b/pandas/core/series.py index 06c744c3e36fa..97d84ffdbab4b 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -943,10 +943,12 @@ def _ixs(self, i: int, axis: AxisInt = 0) -> Any: """ return self._values[i] - def _slice(self, slobj: slice | np.ndarray, axis: Axis = 0) -> Series: + def _slice(self, slobj: slice, axis: AxisInt = 0) -> Series: # axis kwarg is retained for compat with NDFrame method # _slice is *always* positional - return self._get_values(slobj) + mgr = self._mgr.get_slice(slobj, axis=axis) + out = self._constructor(mgr, fastpath=True) + return out.__finalize__(self) def __getitem__(self, key): check_dict_or_set_indexers(key) @@ -983,10 +985,7 @@ def __getitem__(self, key): if isinstance(key, slice): # Do slice check before somewhat-costly is_bool_indexer - # _convert_slice_indexer to determine if this slice is positional - # or label based, and if the latter, convert to positional - slobj = self.index._convert_slice_indexer(key, kind="getitem") - return self._slice(slobj) + return self._getitem_slice(key) if is_iterator(key): key = list(key)