Skip to content

Commit 54b4037

Browse files
phofljbrockmendel
andauthored
Backport PR on Branch 1.5.x (REV: revert deprecation of Series.__getitem__ slicing with IntegerIndex) (pandas-dev#50694)
* REV: revert deprecation of Series.__getitem__ slicing with IntegerIndex (pandas-dev#50283) (cherry picked from commit 1613f26) * Avoid unrelated changes * Fix Co-authored-by: jbrockmendel <[email protected]>
1 parent 71db310 commit 54b4037

File tree

10 files changed

+15
-68
lines changed

10 files changed

+15
-68
lines changed

doc/source/whatsnew/v1.5.3.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ Other
4646
you may see a ``sqlalchemy.exc.RemovedIn20Warning``. These warnings can be safely ignored for the SQLAlchemy 1.4.x releases
4747
as pandas works toward compatibility with SQLAlchemy 2.0.
4848

49-
-
49+
- Reverted deprecation (:issue:`45324`) of behavior of :meth:`Series.__getitem__` and :meth:`Series.__setitem__` slicing with an integer :class:`Index`; this will remain positional (:issue:`49612`)
5050
-
5151

5252
.. ---------------------------------------------------------------------------

pandas/core/indexes/base.py

+2-45
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@
123123
ABCDatetimeIndex,
124124
ABCMultiIndex,
125125
ABCPeriodIndex,
126-
ABCRangeIndex,
127126
ABCSeries,
128127
ABCTimedeltaIndex,
129128
)
@@ -4213,7 +4212,7 @@ def _validate_positional_slice(self, key: slice) -> None:
42134212
self._validate_indexer("positional", key.stop, "iloc")
42144213
self._validate_indexer("positional", key.step, "iloc")
42154214

4216-
def _convert_slice_indexer(self, key: slice, kind: str_t, is_frame: bool = False):
4215+
def _convert_slice_indexer(self, key: slice, kind: str_t):
42174216
"""
42184217
Convert a slice indexer.
42194218
@@ -4224,9 +4223,6 @@ def _convert_slice_indexer(self, key: slice, kind: str_t, is_frame: bool = False
42244223
----------
42254224
key : label of the slice bound
42264225
kind : {'loc', 'getitem'}
4227-
is_frame : bool, default False
4228-
Whether this is a slice called on DataFrame.__getitem__
4229-
as opposed to Series.__getitem__
42304226
"""
42314227
assert kind in ["loc", "getitem"], kind
42324228

@@ -4248,46 +4244,7 @@ def is_int(v):
42484244
is_positional = is_index_slice and ints_are_positional
42494245

42504246
if kind == "getitem":
4251-
"""
4252-
called from the getitem slicers, validate that we are in fact
4253-
integers
4254-
"""
4255-
if self.is_integer():
4256-
if is_frame:
4257-
# unambiguously positional, no deprecation
4258-
pass
4259-
elif start is None and stop is None:
4260-
# label-based vs positional is irrelevant
4261-
pass
4262-
elif isinstance(self, ABCRangeIndex) and self._range == range(
4263-
len(self)
4264-
):
4265-
# In this case there is no difference between label-based
4266-
# and positional, so nothing will change.
4267-
pass
4268-
elif (
4269-
self.dtype.kind in ["i", "u"]
4270-
and self._is_strictly_monotonic_increasing
4271-
and len(self) > 0
4272-
and self[0] == 0
4273-
and self[-1] == len(self) - 1
4274-
):
4275-
# We are range-like, e.g. created with Index(np.arange(N))
4276-
pass
4277-
elif not is_index_slice:
4278-
# we're going to raise, so don't bother warning, e.g.
4279-
# test_integer_positional_indexing
4280-
pass
4281-
else:
4282-
warnings.warn(
4283-
"The behavior of `series[i:j]` with an integer-dtype index "
4284-
"is deprecated. In a future version, this will be treated "
4285-
"as *label-based* indexing, consistent with e.g. `series[i]` "
4286-
"lookups. To retain the old behavior, use `series.iloc[i:j]`. "
4287-
"To get the future behavior, use `series.loc[i:j]`.",
4288-
FutureWarning,
4289-
stacklevel=find_stack_level(),
4290-
)
4247+
# called from the getitem slicers, validate that we are in fact integers
42914248
if self.is_integer() or is_index_slice:
42924249
# Note: these checks are redundant if we know is_index_slice
42934250
self._validate_indexer("slice", key.start, "getitem")

pandas/core/indexes/interval.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -779,7 +779,7 @@ def _index_as_unique(self) -> bool:
779779
"cannot handle overlapping indices; use IntervalIndex.get_indexer_non_unique"
780780
)
781781

782-
def _convert_slice_indexer(self, key: slice, kind: str, is_frame: bool = False):
782+
def _convert_slice_indexer(self, key: slice, kind: str):
783783
if not (key.step is None or key.step == 1):
784784
# GH#31658 if label-based, we require step == 1,
785785
# if positional, we disallow float start/stop
@@ -791,7 +791,7 @@ def _convert_slice_indexer(self, key: slice, kind: str, is_frame: bool = False):
791791
# i.e. this cannot be interpreted as a positional slice
792792
raise ValueError(msg)
793793

794-
return super()._convert_slice_indexer(key, kind, is_frame=is_frame)
794+
return super()._convert_slice_indexer(key, kind)
795795

796796
@cache_readonly
797797
def _should_fallback_to_positional(self) -> bool:

pandas/core/indexes/numeric.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ def _should_fallback_to_positional(self) -> bool:
219219
return False
220220

221221
@doc(Index._convert_slice_indexer)
222-
def _convert_slice_indexer(self, key: slice, kind: str, is_frame: bool = False):
222+
def _convert_slice_indexer(self, key: slice, kind: str):
223223
# TODO(2.0): once #45324 deprecation is enforced we should be able
224224
# to simplify this.
225225
if is_float_dtype(self.dtype):
@@ -231,7 +231,7 @@ def _convert_slice_indexer(self, key: slice, kind: str, is_frame: bool = False):
231231
# translate to locations
232232
return self.slice_indexer(key.start, key.stop, key.step)
233233

234-
return super()._convert_slice_indexer(key, kind=kind, is_frame=is_frame)
234+
return super()._convert_slice_indexer(key, kind=kind)
235235

236236
@doc(Index._maybe_cast_slice_bound)
237237
def _maybe_cast_slice_bound(self, label, side: str, kind=lib.no_default):

pandas/core/indexing.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2491,7 +2491,7 @@ def convert_to_index_sliceable(obj: DataFrame, key):
24912491
"""
24922492
idx = obj.index
24932493
if isinstance(key, slice):
2494-
return idx._convert_slice_indexer(key, kind="getitem", is_frame=True)
2494+
return idx._convert_slice_indexer(key, kind="getitem")
24952495

24962496
elif isinstance(key, str):
24972497

pandas/tests/extension/base/getitem.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,7 @@ def test_get(self, data):
313313
expected = s.iloc[[2, 3]]
314314
self.assert_series_equal(result, expected)
315315

316-
with tm.assert_produces_warning(FutureWarning, match="label-based"):
317-
result = s.get(slice(2))
316+
result = s.get(slice(2))
318317
expected = s.iloc[[0, 1]]
319318
self.assert_series_equal(result, expected)
320319

pandas/tests/indexing/test_floats.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,7 @@ def test_integer_positional_indexing(self, idx):
340340
"""
341341
s = Series(range(2, 6), index=range(2, 6))
342342

343-
with tm.assert_produces_warning(FutureWarning, match="label-based"):
344-
result = s[2:4]
343+
result = s[2:4]
345344
expected = s.iloc[2:4]
346345
tm.assert_series_equal(result, expected)
347346

pandas/tests/series/indexing/test_get.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,7 @@ def test_get_with_ea(arr):
167167
expected = ser.iloc[[2, 3]]
168168
tm.assert_series_equal(result, expected)
169169

170-
with tm.assert_produces_warning(FutureWarning, match="label-based"):
171-
result = ser.get(slice(2))
170+
result = ser.get(slice(2))
172171
expected = ser.iloc[[0, 1]]
173172
tm.assert_series_equal(result, expected)
174173

pandas/tests/series/indexing/test_getitem.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -338,8 +338,7 @@ def test_getitem_slice_bug(self):
338338
def test_getitem_slice_integers(self):
339339
ser = Series(np.random.randn(8), index=[2, 4, 6, 8, 10, 12, 14, 16])
340340

341-
with tm.assert_produces_warning(FutureWarning, match="label-based"):
342-
result = ser[:4]
341+
result = ser[:4]
343342
expected = Series(ser.values[:4], index=[2, 4, 6, 8])
344343
tm.assert_series_equal(result, expected)
345344

pandas/tests/series/indexing/test_setitem.py

+3-9
Original file line numberDiff line numberDiff line change
@@ -220,15 +220,9 @@ def test_setitem_slice(self):
220220
def test_setitem_slice_integers(self):
221221
ser = Series(np.random.randn(8), index=[2, 4, 6, 8, 10, 12, 14, 16])
222222

223-
msg = r"In a future version, this will be treated as \*label-based\* indexing"
224-
with tm.assert_produces_warning(FutureWarning, match=msg):
225-
ser[:4] = 0
226-
with tm.assert_produces_warning(
227-
FutureWarning, match=msg, check_stacklevel=False
228-
):
229-
assert (ser[:4] == 0).all()
230-
with tm.assert_produces_warning(FutureWarning, match=msg):
231-
assert not (ser[4:] == 0).any()
223+
ser[:4] = 0
224+
assert (ser[:4] == 0).all()
225+
assert not (ser[4:] == 0).any()
232226

233227
def test_setitem_slicestep(self):
234228
# caught this bug when writing tests

0 commit comments

Comments
 (0)