Skip to content

REGR: revert behaviour of getitem with assigning with a Series #37502

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
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/source/whatsnew/v1.1.4.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Fixed regressions
- Fixed regression in certain offsets (:meth:`pd.offsets.Day() <pandas.tseries.offsets.Day>` and below) no longer being hashable (:issue:`37267`)
- Fixed regression in :class:`StataReader` which required ``chunksize`` to be manually set when using an iterator to read a dataset (:issue:`37280`)
- Fixed regression in setitem with :meth:`DataFrame.iloc` which raised error when trying to set a value while filtering with a boolean list (:issue:`36741`)
- Fixed regression in setitem with a Series getting aligned before setting the values (:issue:`37427`)
- Fixed regression in :attr:`MultiIndex.is_monotonic_increasing` returning wrong results with ``NaN`` in at least one of the levels (:issue:`37220`)

.. ---------------------------------------------------------------------------
Expand Down
24 changes: 19 additions & 5 deletions pandas/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -1048,10 +1048,8 @@ def _set_with_engine(self, key, value):
def _set_with(self, key, value):
# other: fancy integer or otherwise
if isinstance(key, slice):
# extract_array so that if we set e.g. ser[-5:] = ser[:5]
# we get the first five values, and not 5 NaNs
indexer = self.index._convert_slice_indexer(key, kind="getitem")
self.iloc[indexer] = extract_array(value, extract_numpy=True)
return self._set_values(indexer, value)

else:
assert not isinstance(key, tuple)
Expand All @@ -1069,12 +1067,28 @@ def _set_with(self, key, value):
# should be caught by the is_bool_indexer check in __setitem__
if key_type == "integer":
if not self.index._should_fallback_to_positional():
self.loc[key] = value
self._set_labels(key, value)
else:
self.iloc[key] = value
self._set_values(key, value)
else:
self.loc[key] = value

def _set_labels(self, key, value):
key = com.asarray_tuplesafe(key)
indexer: np.ndarray = self.index.get_indexer(key)
mask = indexer == -1
if mask.any():
raise KeyError(f"{key[mask]} not in index")
self._set_values(indexer, value)

def _set_values(self, key, value):
if isinstance(key, Series):
key = key._values
self._mgr = self._mgr.setitem( # type: ignore[assignment]
indexer=key, value=value
)
self._maybe_update_cacher()

def _set_value(self, label, value, takeable: bool = False):
"""
Quickly set single value at passed label.
Expand Down
10 changes: 10 additions & 0 deletions pandas/tests/series/indexing/test_getitem.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,3 +290,13 @@ def test_getitem_multilevel_scalar_slice_not_implemented(
msg = r"\(2000, slice\(3, 4, None\)\)"
with pytest.raises(TypeError, match=msg):
ser[2000, 3:4]


def test_getitem_assignment_series_aligment():
# https://github.com/pandas-dev/pandas/issues/37427
# with getitem, when assigning with a Series, it is not first aligned
s = Series(range(10))
idx = np.array([2, 4, 9])
s[idx] = Series([10, 11, 12])
expected = Series([0, 1, 10, 3, 11, 5, 6, 7, 8, 12])
tm.assert_series_equal(s, expected)