From 4caaf95d7624d255b6fabdc0b5b778ca9ab066c3 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Sat, 1 Feb 2020 06:22:05 -0800 Subject: [PATCH] Backport PR #31515: REGR: DataFrame.__setitem__(slice, val) is positional --- doc/source/whatsnew/v1.0.1.rst | 2 +- pandas/core/frame.py | 5 ++++- pandas/tests/frame/indexing/test_indexing.py | 9 +++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v1.0.1.rst b/doc/source/whatsnew/v1.0.1.rst index 2d209b375840e..efa2f79fc7cb2 100644 --- a/doc/source/whatsnew/v1.0.1.rst +++ b/doc/source/whatsnew/v1.0.1.rst @@ -76,7 +76,7 @@ Interval Indexing ^^^^^^^^ - +- Fixed regression in :class:`DataFrame` setting values with a slice (e.g. ``df[-4:] = 1``) indexing by label instead of position (:issue:`31469`) - - - Bug where assigning to a :class:`Series` using a IntegerArray / BooleanArray as a mask would raise ``TypeError`` (:issue:`31446`) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index cfd37ac961413..b680234cb0afd 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -2938,8 +2938,11 @@ def __setitem__(self, key, value): self._set_item(key, value) def _setitem_slice(self, key, value): + # NB: we can't just use self.loc[key] = value because that + # operates on labels and we need to operate positional for + # backwards-compat, xref GH#31469 self._check_setitem_copy() - self.loc[key] = value + self.loc._setitem_with_indexer(key, value) def _setitem_array(self, key, value): # also raises Exception if object array with NA values diff --git a/pandas/tests/frame/indexing/test_indexing.py b/pandas/tests/frame/indexing/test_indexing.py index 33c0e92845484..46be2f7d8fe89 100644 --- a/pandas/tests/frame/indexing/test_indexing.py +++ b/pandas/tests/frame/indexing/test_indexing.py @@ -860,6 +860,15 @@ def test_fancy_getitem_slice_mixed(self, float_frame, float_string_frame): assert (float_frame["C"] == 4).all() + def test_setitem_slice_position(self): + # GH#31469 + df = pd.DataFrame(np.zeros((100, 1))) + df[-4:] = 1 + arr = np.zeros((100, 1)) + arr[-4:] = 1 + expected = pd.DataFrame(arr) + tm.assert_frame_equal(df, expected) + def test_getitem_setitem_non_ix_labels(self): df = tm.makeTimeDataFrame()