Skip to content

Commit a5b666c

Browse files
authored
Bug in loc not ordering rhs correctly for mixed indexer (#40764)
1 parent 6967785 commit a5b666c

File tree

2 files changed

+17
-9
lines changed

2 files changed

+17
-9
lines changed

pandas/core/indexing.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -1873,7 +1873,11 @@ def _setitem_single_column(self, loc: int, value, plane_indexer):
18731873
if com.is_null_slice(pi) or com.is_full_slice(pi, len(self.obj)):
18741874
ser = value
18751875
elif is_array_like(value) and is_exact_shape_match(ser, value):
1876-
ser = value
1876+
if is_list_like(pi):
1877+
ser = value[np.argsort(pi)]
1878+
else:
1879+
# in case of slice
1880+
ser = value[pi]
18771881
else:
18781882
# set the item, possibly having a dtype change
18791883
ser = ser.copy()

pandas/tests/indexing/test_loc.py

+12-8
Original file line numberDiff line numberDiff line change
@@ -597,17 +597,13 @@ def test_loc_setitem_frame_with_reindex(self, using_array_manager):
597597
ser = Series([2, 3, 1], index=[3, 5, 4], dtype=float)
598598
if using_array_manager:
599599
# TODO(ArrayManager) with "split" path, we still overwrite the column
600-
# and therefore don't take the order of the indexer into account
601-
ser = Series([1, 2, 3], index=[3, 5, 4], dtype="int64")
600+
# and therefore don't take the dtype of the underlying object into account
601+
ser = Series([2, 3, 1], index=[3, 5, 4], dtype="int64")
602602
expected = DataFrame({"A": ser})
603603
tm.assert_frame_equal(df, expected)
604604

605-
@pytest.mark.xfail(reason="split path wrong update - GH40480")
606605
def test_loc_setitem_frame_with_reindex_mixed(self):
607-
# same test as above, but with mixed dataframe
608-
# TODO with "split" path we still actually overwrite the column
609-
# and therefore don't take the order of the indexer into account
610-
# -> this is a bug: https://github.com/pandas-dev/pandas/issues/40480
606+
# GH#40480
611607
df = DataFrame(index=[3, 5, 4], columns=["A", "B"], dtype=float)
612608
df["B"] = "string"
613609
df.loc[[4, 3, 5], "A"] = np.array([1, 2, 3], dtype="int64")
@@ -616,8 +612,16 @@ def test_loc_setitem_frame_with_reindex_mixed(self):
616612
expected["B"] = "string"
617613
tm.assert_frame_equal(df, expected)
618614

615+
def test_loc_setitem_frame_with_inverted_slice(self):
616+
# GH#40480
617+
df = DataFrame(index=[1, 2, 3], columns=["A", "B"], dtype=float)
618+
df["B"] = "string"
619+
df.loc[slice(3, 0, -1), "A"] = np.array([1, 2, 3], dtype="int64")
620+
expected = DataFrame({"A": [3, 2, 1], "B": "string"}, index=[1, 2, 3])
621+
tm.assert_frame_equal(df, expected)
622+
619623
# TODO(ArrayManager) "split" path overwrites column and therefore don't take
620-
# the order of the indexer into account
624+
# the dtype of the underlying object into account
621625
@td.skip_array_manager_not_yet_implemented
622626
def test_loc_setitem_empty_frame(self):
623627
# GH#6252 setting with an empty frame

0 commit comments

Comments
 (0)