Skip to content

Commit

Permalink
Backport PR #51585 on branch 2.0.x (BUG: not broadcasting when settin…
Browse files Browse the repository at this point in the history
…g empty object) (#51618)

Backport PR #51585: BUG: not broadcasting when setting empty object

Co-authored-by: Patrick Hoefler <61934744+phofl@users.noreply.github.com>
  • Loading branch information
meeseeksmachine and phofl committed Feb 24, 2023
1 parent 0c5a570 commit 7128ade
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 12 deletions.
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 @@ -1276,6 +1276,7 @@ Indexing
- Bug in :meth:`DataFrame.sort_values` where ``None`` was not returned when ``by`` is empty list and ``inplace=True`` (:issue:`50643`)
- 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 all ``False`` ``bool`` indexer and empty object (:issue:`51450`)
- 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.__getitem__`, :meth:`Series.__getitem__`, :meth:`DataFrame.__setitem__` and :meth:`Series.__setitem__`
Expand Down
14 changes: 2 additions & 12 deletions pandas/core/indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@
)
from pandas.core.indexers import (
check_array_indexer,
is_empty_indexer,
is_list_like_indexer,
is_scalar_indexer,
length_of_indexer,
Expand Down Expand Up @@ -755,14 +754,8 @@ def _maybe_mask_setitem_value(self, indexer, value):
if ndim == 1:
# We implicitly broadcast, though numpy does not, see
# github.com/pandas-dev/pandas/pull/45501#discussion_r789071825
if len(newkey) == 0:
# FIXME: kludge for
# test_setitem_loc_only_false_indexer_dtype_changed
# TODO(GH#45333): may be fixed when deprecation is enforced
value = value.iloc[:0]
else:
# test_loc_setitem_ndframe_values_alignment
value = self.obj.iloc._align_series(indexer, value)
# test_loc_setitem_ndframe_values_alignment
value = self.obj.iloc._align_series(indexer, value)
indexer = (newkey, icols)

elif ndim == 2 and value.shape[1] == 1:
Expand Down Expand Up @@ -2239,9 +2232,6 @@ def ravel(i):
# we have a frame, with multiple indexers on both axes; and a
# series, so need to broadcast (see GH5206)
if sum_aligners == self.ndim and all(is_sequence(_) for _ in indexer):
# TODO: This is hacky, align Series and DataFrame behavior GH#45778
if obj.ndim == 2 and is_empty_indexer(indexer[0]):
return ser._values.copy()
ser_values = ser.reindex(obj.axes[0][indexer[0]], copy=True)._values

# single indexer
Expand Down
14 changes: 14 additions & 0 deletions pandas/tests/indexing/test_loc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2599,6 +2599,20 @@ def test_loc_setitem_ndframe_values_alignment(self, using_copy_on_write):
else:
tm.assert_frame_equal(df, expected)

def test_loc_indexer_empty_broadcast(self):
# GH#51450
df = DataFrame({"a": [], "b": []}, dtype=object)
expected = df.copy()
df.loc[np.array([], dtype=np.bool_), ["a"]] = df["a"]
tm.assert_frame_equal(df, expected)

def test_loc_indexer_all_false_broadcast(self):
# GH#51450
df = DataFrame({"a": ["x"], "b": ["y"]}, dtype=object)
expected = df.copy()
df.loc[np.array([False], dtype=np.bool_), ["a"]] = df["b"]
tm.assert_frame_equal(df, expected)


class TestLocListlike:
@pytest.mark.parametrize("box", [lambda x: x, np.asarray, list])
Expand Down

0 comments on commit 7128ade

Please sign in to comment.