diff --git a/doc/source/whatsnew/v2.0.0.rst b/doc/source/whatsnew/v2.0.0.rst index 12b0d90e68ab9..f6e0b5bc0cf36 100644 --- a/doc/source/whatsnew/v2.0.0.rst +++ b/doc/source/whatsnew/v2.0.0.rst @@ -853,6 +853,7 @@ Indexing - Bug in :meth:`DataFrame.loc` coercing dtypes when setting values with a list indexer (:issue:`49159`) - Bug in :meth:`Series.loc` raising error for out of bounds end of slice indexer (:issue:`50161`) - Bug in :meth:`DataFrame.loc` raising ``ValueError`` with ``bool`` indexer and :class:`MultiIndex` (:issue:`47687`) +- Bug in :meth:`DataFrame.loc` raising ``IndexError`` when setting values for a pyarrow-backed column with a non-scalar indexer (:issue:`50085`) - Bug in :meth:`DataFrame.__setitem__` raising ``ValueError`` when right hand side is :class:`DataFrame` with :class:`MultiIndex` columns (:issue:`49121`) - Bug in :meth:`DataFrame.reindex` casting dtype to ``object`` when :class:`DataFrame` has single extension array column when re-indexing ``columns`` and ``index`` (:issue:`48190`) - Bug in :meth:`DataFrame.iloc` raising ``IndexError`` when indexer is a :class:`Series` with numeric extension array dtype (:issue:`49521`) diff --git a/pandas/core/arrays/arrow/array.py b/pandas/core/arrays/arrow/array.py index 7e954b3d1d1ec..f5ff4f4b2dc7c 100644 --- a/pandas/core/arrays/arrow/array.py +++ b/pandas/core/arrays/arrow/array.py @@ -951,7 +951,7 @@ def pyarrow_meth(data, skip_nulls, **kwargs): return self.dtype.na_value return result.as_py() - def __setitem__(self, key: int | slice | np.ndarray, value: Any) -> None: + def __setitem__(self, key, value) -> None: """Set one or more values inplace. Parameters @@ -972,6 +972,10 @@ def __setitem__(self, key: int | slice | np.ndarray, value: Any) -> None: ------- None """ + # GH50085: unwrap 1D indexers + if isinstance(key, tuple) and len(key) == 1: + key = key[0] + key = check_array_indexer(self, key) value = self._maybe_convert_setitem_value(value) @@ -997,7 +1001,6 @@ def __setitem__(self, key: int | slice | np.ndarray, value: Any) -> None: return indices = self._indexing_key_to_indices(key) - argsort = np.argsort(indices) indices = indices[argsort] diff --git a/pandas/core/arrays/base.py b/pandas/core/arrays/base.py index 6954c97007d23..422b9effeface 100644 --- a/pandas/core/arrays/base.py +++ b/pandas/core/arrays/base.py @@ -348,7 +348,7 @@ def __getitem__( """ raise AbstractMethodError(self) - def __setitem__(self, key: int | slice | np.ndarray, value: Any) -> None: + def __setitem__(self, key, value) -> None: """ Set one or more values inplace. diff --git a/pandas/core/arrays/datetimelike.py b/pandas/core/arrays/datetimelike.py index 63940741c3fe3..50069b6e65cfa 100644 --- a/pandas/core/arrays/datetimelike.py +++ b/pandas/core/arrays/datetimelike.py @@ -407,7 +407,7 @@ def _get_getitem_freq(self, key) -> BaseOffset | None: # error: Argument 1 of "__setitem__" is incompatible with supertype # "ExtensionArray"; supertype defines the argument type as "Union[int, # ndarray]" - def __setitem__( # type: ignore[override] + def __setitem__( self, key: int | Sequence[int] | Sequence[bool] | slice, value: NaTType | Any | Sequence[Any], diff --git a/pandas/tests/extension/base/setitem.py b/pandas/tests/extension/base/setitem.py index f52abb9349578..73445a96f4a03 100644 --- a/pandas/tests/extension/base/setitem.py +++ b/pandas/tests/extension/base/setitem.py @@ -418,3 +418,11 @@ def test_setitem_invalid(self, data, invalid_scalar): with pytest.raises((ValueError, TypeError), match=msg): data[:] = invalid_scalar + + def test_setitem_2d_values(self, data): + # GH50085 + original = data.copy() + df = pd.DataFrame({"a": data, "b": data}) + df.loc[[0, 1], :] = df.loc[[1, 0], :].values + assert (df.loc[0, :] == original[1]).all() + assert (df.loc[1, :] == original[0]).all()