-
- Notifications
You must be signed in to change notification settings - Fork 19.4k
Closed
Labels
API - ConsistencyInternal Consistency of API/BehaviorInternal Consistency of API/BehaviorIndexingRelated to indexing on series/frames, not to indexes themselvesRelated to indexing on series/frames, not to indexes themselvesNeeds DiscussionRequires discussion from core team before further actionRequires discussion from core team before further action
Milestone
Description
When we have a Int64Index, series[i] is treated as label-based. For consistency, series[i:j] should be too.
ser = pd.Series(range(5), index=pd.Index([1, 3, 5, 7, 9])) ser2 = ser.copy() ser2.index = ser2.index.astype('f8') >>> ser[1] # <- label-based 0 >>> ser[1:3] # <- positional 3 1 5 2 dtype: int64 >>> ser2[1:3] # <- label-based 1.0 0 3.0 1 dtype: int64 The logic by which ser[i:j] is positional is not easy to track down and does not use modern idioms (i.e. _should_fallback_to_positional)
NumericIndex._convert_slice_indexer specifically special-cases floating dtypes
def _convert_slice_indexer(self, key: slice, kind: str): if is_float_dtype(self.dtype): assert kind in ["loc", "getitem"] # We always treat __getitem__ slicing as label-based # translate to locations return self.slice_indexer(key.start, key.stop, key.step) return super()._convert_slice_indexer(key, kind=kind) while the base class ...
def _convert_slice_indexer(self, key: slice, kind: str_t): # potentially cast the bounds to integers start, stop, step = key.start, key.stop, key.step # figure out if this is a positional indexer def is_int(v): return v is None or is_integer(v) is_index_slice = is_int(start) and is_int(stop) and is_int(step) is_positional = is_index_slice and not (self.is_integer() or self.is_categorical()) if kind == "getitem": """ called from the getitem slicers, validate that we are in fact integers """ if self.is_integer() or is_index_slice: self._validate_indexer("slice", key.start, "getitem") self._validate_indexer("slice", key.stop, "getitem") self._validate_indexer("slice", key.step, "getitem") return key AFAICT the is_positional = is_index_slice and not (self.is_integer() or self.is_categorical()) check should be is_positional = is_index_slice and self._should_fallback_to_positional. The if self.is_integer() or is_index_slice: should probably also be done in terms of _should_fallback_to_positional
Expected Behavior
>>> ser[1:3] # <- match ser.loc[1:3] 1 0 3 1 dtype: int64 Metadata
Metadata
Assignees
Labels
API - ConsistencyInternal Consistency of API/BehaviorInternal Consistency of API/BehaviorIndexingRelated to indexing on series/frames, not to indexes themselvesRelated to indexing on series/frames, not to indexes themselvesNeeds DiscussionRequires discussion from core team before further actionRequires discussion from core team before further action