Skip to content

BUG: unwrap setitem indexer for ArrowExtensionArray #50085

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jan 4, 2023
1 change: 1 addition & 0 deletions doc/source/whatsnew/v2.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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`)
Expand Down
7 changes: 5 additions & 2 deletions pandas/core/arrays/arrow/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)

Expand All @@ -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]

Expand Down
2 changes: 1 addition & 1 deletion pandas/core/arrays/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
2 changes: 1 addition & 1 deletion pandas/core/arrays/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand Down
8 changes: 8 additions & 0 deletions pandas/tests/extension/base/setitem.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()