diff --git a/asv_bench/benchmarks/indexing.py b/asv_bench/benchmarks/indexing.py index 15e691d46f693..7d34b6aa9372f 100644 --- a/asv_bench/benchmarks/indexing.py +++ b/asv_bench/benchmarks/indexing.py @@ -47,7 +47,7 @@ def time_getitem_scalar(self, index, index_structure): self.data[800000] def time_getitem_slice(self, index, index_structure): - self.data[:800000] + self.data.loc[:800000] def time_getitem_list_like(self, index, index_structure): self.data[[800000]] diff --git a/doc/source/whatsnew/v0.13.0.rst b/doc/source/whatsnew/v0.13.0.rst index a624e81d17db9..ceb16bc7a8d8d 100644 --- a/doc/source/whatsnew/v0.13.0.rst +++ b/doc/source/whatsnew/v0.13.0.rst @@ -342,12 +342,25 @@ Float64Index API change Slicing is ALWAYS on the values of the index, for ``[],ix,loc`` and ALWAYS positional with ``iloc`` - .. ipython:: python - :okwarning: + .. code-block:: ipython + + In [1]: s[2:4] + Out[23]: + 2.0 1 + 3.0 2 + dtype: int64 + + In [24]: s.loc[2:4] + Out[24]: + 2.0 1 + 3.0 2 + dtype: int64 - s[2:4] - s.loc[2:4] - s.iloc[2:4] + In[25]: s.iloc[2:4] + Out[25]: + 3.0 2 + 4.5 3 + dtype: int64 In float indexes, slicing using floats are allowed diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index c77348b365370..05d0e815f22f3 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -240,6 +240,7 @@ Removal of prior version deprecations/changes - Removed the "closed" and "unit" keywords in :meth:`TimedeltaIndex.__new__` (:issue:`52628`, :issue:`55499`) - All arguments in :meth:`Index.sort_values` are now keyword only (:issue:`56493`) - All arguments in :meth:`Series.to_dict` are now keyword only (:issue:`56493`) +- Changed the behavior of :meth:`Series.__getitem__`, :meth:`Series.__setitem__`, :meth:`DataFrame.__getitem__`, :meth:`DataFrame.__setitem__` with an integer slice on objects with a floating-dtype index from label-based to a *positional* indexing (:issue:`58449`) - Changed the default value of ``observed`` in :meth:`DataFrame.groupby` and :meth:`Series.groupby` to ``True`` (:issue:`51811`) - Enforce deprecation in :func:`testing.assert_series_equal` and :func:`testing.assert_frame_equal` with object dtype and mismatched null-like values, which are now considered not-equal (:issue:`18463`) - Enforced deprecation ``all`` and ``any`` reductions with ``datetime64``, :class:`DatetimeTZDtype`, and :class:`PeriodDtype` dtypes (:issue:`58029`) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 9acab2642f6be..a9085424b0ced 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -3842,20 +3842,7 @@ def _convert_slice_indexer(self, key: slice, kind: Literal["loc", "getitem"]): # We always treat __getitem__ slicing as label-based # translate to locations if kind == "getitem" and is_index_slice and not start == stop and step != 0: - # exclude step=0 from the warning because it will raise anyway - # start/stop both None e.g. [:] or [::-1] won't change. - # exclude start==stop since it will be empty either way, or - # will be [:] or [::-1] which won't change - warnings.warn( - # GH#49612 - "The behavior of obj[i:j] with a float-dtype index is " - "deprecated. In a future version, this will be treated as " - "positional instead of label-based. For label-based slicing, " - "use obj.loc[i:j] instead", - FutureWarning, - stacklevel=find_stack_level(), - ) - return self.slice_indexer(start, stop, step) + self.loc[start:stop] # type: ignore[attr-defined] if kind == "getitem": # called from the getitem slicers, validate that we are in fact integers diff --git a/pandas/tests/frame/indexing/test_indexing.py b/pandas/tests/frame/indexing/test_indexing.py index 69e6228d6efde..3fe52129d1f70 100644 --- a/pandas/tests/frame/indexing/test_indexing.py +++ b/pandas/tests/frame/indexing/test_indexing.py @@ -748,10 +748,7 @@ def test_getitem_setitem_float_labels(self): expected = df.iloc[0:2] tm.assert_frame_equal(result, expected) - expected = df.iloc[0:2] - msg = r"The behavior of obj\[i:j\] with a float-dtype index" - with tm.assert_produces_warning(FutureWarning, match=msg): - result = df[1:2] + result = df.loc[1:2] tm.assert_frame_equal(result, expected) # #2727 diff --git a/pandas/tests/indexing/test_floats.py b/pandas/tests/indexing/test_floats.py index 1fe431e12f2a1..4edb3fac6495b 100644 --- a/pandas/tests/indexing/test_floats.py +++ b/pandas/tests/indexing/test_floats.py @@ -491,11 +491,11 @@ def test_floating_misc(self, indexer_sl): for fancy_idx in [[5, 0], np.array([5, 0])]: tm.assert_series_equal(indexer_sl(s)[fancy_idx], expected) - warn = FutureWarning if indexer_sl is tm.setitem else None - msg = r"The behavior of obj\[i:j\] with a float-dtype index" - # all should return the same as we are slicing 'the same' - with tm.assert_produces_warning(warn, match=msg): + + if indexer_sl is tm.setitem: + result1 = indexer_sl(s).loc[2:5] + else: result1 = indexer_sl(s)[2:5] result2 = indexer_sl(s)[2.0:5.0] result3 = indexer_sl(s)[2.0:5] @@ -505,7 +505,9 @@ def test_floating_misc(self, indexer_sl): tm.assert_series_equal(result1, result4) expected = Series([1, 2], index=[2.5, 5.0]) - with tm.assert_produces_warning(warn, match=msg): + if indexer_sl is tm.setitem: + result = indexer_sl(s).loc[2:5] + else: result = indexer_sl(s)[2:5] tm.assert_series_equal(result, expected)