Skip to content

API: series_with_int64index[i:j] should be label-based #45162

@jbrockmendel

Description

@jbrockmendel

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

No one assigned

    Labels

    API - ConsistencyInternal Consistency of API/BehaviorIndexingRelated to indexing on series/frames, not to indexes themselvesNeeds DiscussionRequires discussion from core team before further action

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions