diff --git a/doc/source/whatsnew/v1.1.4.rst b/doc/source/whatsnew/v1.1.4.rst index 33a52353bed7e..332be365e3763 100644 --- a/doc/source/whatsnew/v1.1.4.rst +++ b/doc/source/whatsnew/v1.1.4.rst @@ -26,6 +26,7 @@ Fixed regressions - Fixed regression where slicing :class:`DatetimeIndex` raised :exc:`AssertionError` on irregular time series with ``pd.NaT`` or on unsorted indices (:issue:`36953` and :issue:`35509`) - Fixed regression in certain offsets (:meth:`pd.offsets.Day() ` and below) no longer being hashable (:issue:`37267`) - Fixed regression in :class:`StataReader` which required ``chunksize`` to be manually set when using an iterator to read a dataset (:issue:`37280`) +- Fixed regression in setitem with :meth:`DataFrame.iloc` which raised error when trying to set a value while filtering with a boolean list (:issue:`36741`) - Fixed regression in :attr:`MultiIndex.is_monotonic_increasing` returning wrong results with ``NaN`` in at least one of the levels (:issue:`37220`) .. --------------------------------------------------------------------------- diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 27ee91fc5465e..3d491c7127e38 100644 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -1670,8 +1670,6 @@ def _setitem_with_indexer(self, indexer, value): "length than the value" ) - pi = plane_indexer[0] if lplane_indexer == 1 else plane_indexer - # we need an iterable, with a ndim of at least 1 # eg. don't pass through np.array(0) if is_list_like_indexer(value) and getattr(value, "ndim", 1) > 0: @@ -1698,7 +1696,7 @@ def _setitem_with_indexer(self, indexer, value): else: v = np.nan - self._setitem_single_column(loc, v, pi) + self._setitem_single_column(loc, v, plane_indexer) elif not unique_cols: raise ValueError( @@ -1716,7 +1714,7 @@ def _setitem_with_indexer(self, indexer, value): else: v = np.nan - self._setitem_single_column(loc, v, pi) + self._setitem_single_column(loc, v, plane_indexer) # we have an equal len ndarray/convertible to our labels # hasattr first, to avoid coercing to ndarray without reason. @@ -1735,7 +1733,9 @@ def _setitem_with_indexer(self, indexer, value): for i, loc in enumerate(ilocs): # setting with a list, re-coerces - self._setitem_single_column(loc, value[:, i].tolist(), pi) + self._setitem_single_column( + loc, value[:, i].tolist(), plane_indexer + ) elif ( len(labels) == 1 @@ -1744,7 +1744,7 @@ def _setitem_with_indexer(self, indexer, value): ): # we have an equal len list/ndarray # We only get here with len(labels) == len(ilocs) == 1 - self._setitem_single_column(ilocs[0], value, pi) + self._setitem_single_column(ilocs[0], value, plane_indexer) elif lplane_indexer == 0 and len(value) == len(self.obj.index): # We get here in one case via .loc with a all-False mask @@ -1759,12 +1759,12 @@ def _setitem_with_indexer(self, indexer, value): ) for loc, v in zip(ilocs, value): - self._setitem_single_column(loc, v, pi) + self._setitem_single_column(loc, v, plane_indexer) else: # scalar value for loc in ilocs: - self._setitem_single_column(loc, value, pi) + self._setitem_single_column(loc, value, plane_indexer) else: self._setitem_single_block(indexer, value) diff --git a/pandas/tests/frame/indexing/test_setitem.py b/pandas/tests/frame/indexing/test_setitem.py index c317e90181a8f..55465dffd2027 100644 --- a/pandas/tests/frame/indexing/test_setitem.py +++ b/pandas/tests/frame/indexing/test_setitem.py @@ -229,3 +229,12 @@ def test_setitem_periodindex(self): rs = df.reset_index().set_index("index") assert isinstance(rs.index, PeriodIndex) tm.assert_index_equal(rs.index, rng) + + @pytest.mark.parametrize("klass", [list, np.array]) + def test_iloc_setitem_bool_indexer(self, klass): + # GH: 36741 + df = DataFrame({"flag": ["x", "y", "z"], "value": [1, 3, 4]}) + indexer = klass([True, False, False]) + df.iloc[indexer, 1] = df.iloc[indexer, 1] * 2 + expected = DataFrame({"flag": ["x", "y", "z"], "value": [2, 3, 4]}) + tm.assert_frame_equal(df, expected)