diff --git a/asv_bench/benchmarks/io/sql.py b/asv_bench/benchmarks/io/sql.py index fb8b7dafa0ade..c1f378e8075e9 100644 --- a/asv_bench/benchmarks/io/sql.py +++ b/asv_bench/benchmarks/io/sql.py @@ -38,7 +38,7 @@ def setup(self, connection): }, index=tm.makeStringIndex(N), ) - self.df.loc[1000:3000, "float_with_nan"] = np.nan + self.df.iloc[1000:3000, 1] = np.nan self.df["date"] = self.df["datetime"].dt.date self.df["time"] = self.df["datetime"].dt.time self.df["datetime_string"] = self.df["datetime"].astype(str) @@ -88,7 +88,7 @@ def setup(self, connection, dtype): }, index=tm.makeStringIndex(N), ) - self.df.loc[1000:3000, "float_with_nan"] = np.nan + self.df.iloc[1000:3000, 1] = np.nan self.df["date"] = self.df["datetime"].dt.date self.df["time"] = self.df["datetime"].dt.time self.df["datetime_string"] = self.df["datetime"].astype(str) @@ -117,7 +117,7 @@ def setup(self): }, index=tm.makeStringIndex(N), ) - self.df.loc[1000:3000, "float_with_nan"] = np.nan + self.df.iloc[1000:3000, 1] = np.nan self.df["date"] = self.df["datetime"].dt.date self.df["time"] = self.df["datetime"].dt.time self.df["datetime_string"] = self.df["datetime"].astype(str) @@ -164,7 +164,7 @@ def setup(self, dtype): }, index=tm.makeStringIndex(N), ) - self.df.loc[1000:3000, "float_with_nan"] = np.nan + self.df.iloc[1000:3000, 1] = np.nan self.df["date"] = self.df["datetime"].dt.date self.df["time"] = self.df["datetime"].dt.time self.df["datetime_string"] = self.df["datetime"].astype(str) diff --git a/doc/source/whatsnew/v2.0.0.rst b/doc/source/whatsnew/v2.0.0.rst index 5aa753dffcf7f..0004bc92b349e 100644 --- a/doc/source/whatsnew/v2.0.0.rst +++ b/doc/source/whatsnew/v2.0.0.rst @@ -256,6 +256,7 @@ Removal of prior version deprecations/changes - Enforced disallowing passing an integer ``fill_value`` to :meth:`DataFrame.shift` and :meth:`Series.shift`` with datetime64, timedelta64, or period dtypes (:issue:`32591`) - Enforced disallowing a string column label into ``times`` in :meth:`DataFrame.ewm` (:issue:`43265`) - Enforced disallowing a tuple of column labels into :meth:`.DataFrameGroupBy.__getitem__` (:issue:`30546`) +- Enforced disallowing setting values with ``.loc`` using a positional slice. Use ``.loc`` with labels or ``.iloc`` with positions instead (:issue:`31840`) - Removed setting Categorical._codes directly (:issue:`41429`) - Enforced :meth:`Rolling.count` with ``min_periods=None`` to default to the size of the window (:issue:`31302`) - Renamed ``fname`` to ``path`` in :meth:`DataFrame.to_parquet`, :meth:`DataFrame.to_stata` and :meth:`DataFrame.to_feather` (:issue:`30338`) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 7571525363447..d8300bb29c274 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -4189,12 +4189,9 @@ def is_int(v): elif is_positional: if kind == "loc": # GH#16121, GH#24612, GH#31810 - warnings.warn( - "Slicing a positional slice with .loc is not supported, " - "and will raise TypeError in a future version. " + raise TypeError( + "Slicing a positional slice with .loc is not allowed, " "Use .loc with labels or .iloc with positions instead.", - FutureWarning, - stacklevel=find_stack_level(), ) indexer = key else: diff --git a/pandas/tests/indexing/test_loc.py b/pandas/tests/indexing/test_loc.py index 3490d05f13e9d..88ae431fb1baf 100644 --- a/pandas/tests/indexing/test_loc.py +++ b/pandas/tests/indexing/test_loc.py @@ -2795,16 +2795,13 @@ def test_loc_mixed_int_float(): assert result == 0 -def test_loc_with_positional_slice_deprecation(): +def test_loc_with_positional_slice_raises(): # GH#31840 ser = Series(range(4), index=["A", "B", "C", "D"]) - with tm.assert_produces_warning(FutureWarning): + with pytest.raises(TypeError, match="Slicing a positional slice with .loc"): ser.loc[:3] = 2 - expected = Series([2, 2, 2, 3], index=["A", "B", "C", "D"]) - tm.assert_series_equal(ser, expected) - def test_loc_slice_disallows_positional(): # GH#16121, GH#24612, GH#31810 @@ -2822,15 +2819,15 @@ def test_loc_slice_disallows_positional(): with pytest.raises(TypeError, match=msg): obj.loc[1:3] - with tm.assert_produces_warning(FutureWarning): - # GH#31840 deprecated incorrect behavior + with pytest.raises(TypeError, match="Slicing a positional slice with .loc"): + # GH#31840 enforce incorrect behavior obj.loc[1:3] = 1 with pytest.raises(TypeError, match=msg): df.loc[1:3, 1] - with tm.assert_produces_warning(FutureWarning): - # GH#31840 deprecated incorrect behavior + with pytest.raises(TypeError, match="Slicing a positional slice with .loc"): + # GH#31840 enforce incorrect behavior df.loc[1:3, 1] = 2