Skip to content
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

Fix59933 #60621

Closed
wants to merge 14 commits into from
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
.vagrant
.noseids
.ipynb_checkpoints
.ipynb
.csv
.tags
.cache/
.vscode/
Expand Down
1 change: 1 addition & 0 deletions doc/source/whatsnew/v3.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,7 @@ Indexing
^^^^^^^^
- Bug in :meth:`DataFrame.__getitem__` returning modified columns when called with ``slice`` in Python 3.12 (:issue:`57500`)
- Bug in :meth:`DataFrame.from_records` throwing a ``ValueError`` when passed an empty list in ``index`` (:issue:`58594`)
- Bug in :meth:`DataFrame.loc` with inconsistent behavior of loc-set with 2 given indexes to Series (:issue:`599333`)
- Bug in :meth:`MultiIndex.insert` when a new value inserted to a datetime-like level gets cast to ``NaT`` and fails indexing (:issue:`60388`)
- Bug in printing :attr:`Index.names` and :attr:`MultiIndex.levels` would not escape single quotes (:issue:`60190`)

Expand Down
15 changes: 12 additions & 3 deletions pandas/core/indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -2353,11 +2353,17 @@ def _align_series(

if isinstance(indexer, tuple):
# flatten np.ndarray indexers
if (
len(indexer) == 2
and isinstance(indexer[1], np.ndarray)
and indexer[1].dtype == np.bool_
):
indexer = (indexer[0], np.where(indexer[1])[0])

def ravel(i):
return i.ravel() if isinstance(i, np.ndarray) else i

indexer = tuple(map(ravel, indexer))

aligners = [not com.is_null_slice(idx) for idx in indexer]
sum_aligners = sum(aligners)
single_aligner = sum_aligners == 1
Expand All @@ -2375,12 +2381,15 @@ 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):
if all(is_sequence(_) or isinstance(_, slice) for _ in indexer):
ser_values = ser.reindex(obj.axes[0][indexer[0]])._values

# single indexer
if len(indexer) > 1 and not multiindex_indexer:
len_indexer = len(indexer[1])
if isinstance(indexer[1], slice):
len_indexer = len(obj.axes[1][indexer[1]])
else:
len_indexer = len(indexer[1])
ser_values = (
np.tile(ser_values, len_indexer).reshape(len_indexer, -1).T
)
Expand Down
60 changes: 60 additions & 0 deletions pandas/tests/indexing/test_loc.py
Original file line number Diff line number Diff line change
Expand Up @@ -3298,6 +3298,66 @@ def test_loc_reindexing_of_empty_index(self):
expected = DataFrame(index=[1, 1, 2, 2], data=["1", "1", "2", "2"])
tm.assert_frame_equal(df, expected)

@pytest.mark.parametrize(
"df, row_index, col_index, expected_df",
[
[
DataFrame([[1, 2, 3], [4, 5, 6]], columns=list("ABC")),
slice(0, 3),
["A", "B", "C"],
DataFrame([[10, 10, 10], [20, 20, 20]], columns=list("ABC")),
],
[
DataFrame([[1, 2, 3], [4, 5, 6]], columns=list("ABC")),
slice(None),
["A", "B", "C"],
DataFrame([[10, 10, 10], [20, 20, 20]], columns=list("ABC")),
],
[
DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 9]], columns=list("ABC")),
[True, True, True],
["A", "B", "C"],
DataFrame(
[[10, 10, 10], [20, 20, 20], [30, 30, 30]], columns=list("ABC")
),
],
[
DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 9]], columns=list("ABC")),
slice(0, 4),
["A", "B", "C"],
DataFrame(
[[10, 10, 10], [20, 20, 20], [30, 30, 30]], columns=list("ABC")
),
],
[
DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 9]], columns=list("ABC")),
slice(None),
slice("A", "C"),
DataFrame(
[[10, 10, 10], [20, 20, 20], [30, 30, 30]], columns=list("ABC")
),
],
[
DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 9]], columns=list("ABC")),
slice(None),
Series(
{
"A": True,
"C": False,
"B": True,
}
),
DataFrame([[10, 10, 3], [20, 20, 6], [30, 30, 9]], columns=list("ABC")),
],
],
)
def test_loc_set_series_to_multiple_columns(
self, df, row_index, col_index, expected_df
):
# GH 59933
df.loc[row_index, col_index] = Series([10, 20, 30])
tm.assert_frame_equal(df, expected_df)

def test_loc_setitem_matching_index(self):
# GH 25548
s = Series(0.0, index=list("abcd"))
Expand Down
Loading