From bac8ef53f2a9b684c92d6f491f431d54eb647849 Mon Sep 17 00:00:00 2001 From: Brock Date: Wed, 1 Dec 2021 16:34:23 -0800 Subject: [PATCH] BUG: df.iloc[ndarray, ndarray] = 2dvals raising with EA column --- doc/source/whatsnew/v1.4.0.rst | 1 + pandas/core/internals/blocks.py | 8 ++++++++ pandas/tests/indexing/test_iloc.py | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/doc/source/whatsnew/v1.4.0.rst b/doc/source/whatsnew/v1.4.0.rst index 9a654720330da..94f796192235d 100644 --- a/doc/source/whatsnew/v1.4.0.rst +++ b/doc/source/whatsnew/v1.4.0.rst @@ -681,6 +681,7 @@ Indexing - Bug in :meth:`DataFrame.loc.__setitem__` and :meth:`DataFrame.iloc.__setitem__` with mixed dtypes sometimes failing to operate in-place (:issue:`44345`) - Bug in :meth:`DataFrame.loc.__getitem__` incorrectly raising ``KeyError`` when selecting a single column with a boolean key (:issue:`44322`). - Bug in setting :meth:`DataFrame.iloc` with a single ``ExtensionDtype`` column and setting 2D values e.g. ``df.iloc[:] = df.values`` incorrectly raising (:issue:`44514`) +- Bug in setting values with :meth:`DataFrame.iloc` with a single ``ExtensionDtype`` column and a tuple of arrays as the indexer (:issue:`44703`) - Bug in indexing on columns with ``loc`` or ``iloc`` using a slice with a negative step with ``ExtensionDtype`` columns incorrectly raising (:issue:`44551`) - Bug in :meth:`IntervalIndex.get_indexer_non_unique` returning boolean mask instead of array of integers for a non unique and non monotonic index (:issue:`44084`) - Bug in :meth:`IntervalIndex.get_indexer_non_unique` not handling targets of ``dtype`` 'object' with NaNs correctly (:issue:`44482`) diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index a172cfa49e5b3..dd45af4a67a47 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -1510,6 +1510,14 @@ def setitem(self, indexer, value): # TODO(EA2D): not needed with 2D EAs # we are always 1-D indexer = indexer[0] + if isinstance(indexer, np.ndarray) and indexer.ndim == 2: + # GH#44703 + if indexer.shape[1] != 1: + raise NotImplementedError( + "This should not be reached. Please report a bug at " + "github.com/pandas-dev/pandas/" + ) + indexer = indexer[:, 0] # TODO(EA2D): not needed with 2D EAS if isinstance(value, (np.ndarray, ExtensionArray)) and value.ndim == 2: diff --git a/pandas/tests/indexing/test_iloc.py b/pandas/tests/indexing/test_iloc.py index e088f1ce87a6a..648e80cc92017 100644 --- a/pandas/tests/indexing/test_iloc.py +++ b/pandas/tests/indexing/test_iloc.py @@ -1158,6 +1158,14 @@ def test_iloc_getitem_slice_negative_step_ea_block(self): expected = DataFrame({"B": df["B"], "A": df["A"]}) tm.assert_frame_equal(res, expected) + def test_iloc_setitem_2d_ndarray_into_ea_block(self): + # GH#44703 + df = DataFrame({"status": ["a", "b", "c"]}, dtype="category") + df.iloc[np.array([0, 1]), np.array([0])] = np.array([["a"], ["a"]]) + + expected = DataFrame({"status": ["a", "a", "c"]}, dtype=df["status"].dtype) + tm.assert_frame_equal(df, expected) + class TestILocErrors: # NB: this test should work for _any_ Series we can pass as