Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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/v3.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -940,6 +940,7 @@ Other
- Bug in Dataframe Interchange Protocol implementation was returning incorrect results for data buffers' associated dtype, for string and datetime columns (:issue:`54781`)
- Bug in ``Series.list`` methods not preserving the original :class:`Index`. (:issue:`58425`)
- Bug in ``Series.list`` methods not preserving the original name. (:issue:`60522`)
- Bug in ``Series.replace`` when the Series was created from an :class:`Index` and Copy-On-Write is enabled (:issue:`61622`)
- Bug in printing a :class:`DataFrame` with a :class:`DataFrame` stored in :attr:`DataFrame.attrs` raised a ``ValueError`` (:issue:`60455`)
- Bug in printing a :class:`Series` with a :class:`DataFrame` stored in :attr:`Series.attrs` raised a ``ValueError`` (:issue:`60568`)
- Fixed bug where the :class:`DataFrame` constructor misclassified array-like objects with a ``.name`` attribute as :class:`Series` or :class:`Index` (:issue:`61443`)
Expand Down
23 changes: 15 additions & 8 deletions pandas/core/internals/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
final,
)
import warnings
import weakref

import numpy as np

Expand Down Expand Up @@ -863,14 +862,22 @@ def replace_list(
)

if i != src_len:
# This is ugly, but we have to get rid of intermediate refs
# that did not go out of scope yet, otherwise we will trigger
# many unnecessary copies
# This is ugly, but we have to get rid of intermediate refs. We
# can simply clear the referenced_blocks if we already copied,
# otherwise we have to remove ourselves
self_blk_ids = {
id(b()): i for i, b in enumerate(self.refs.referenced_blocks)
}
for b in result:
ref = weakref.ref(b)
b.refs.referenced_blocks.pop(
b.refs.referenced_blocks.index(ref)
)
if b.refs is self.refs:
# We are still sharing memory with self
if id(b) in self_blk_ids:
# Remove ourselves from the refs; we are temporary
self.refs.referenced_blocks.pop(self_blk_ids[id(b)])
else:
# We have already copied, so we can clear the refs to avoid
# future copies
b.refs.referenced_blocks.clear()
new_rb.extend(result)
rb = new_rb
return rb
Expand Down
8 changes: 8 additions & 0 deletions pandas/tests/series/methods/test_replace.py
Original file line number Diff line number Diff line change
Expand Up @@ -715,3 +715,11 @@ def test_replace_all_NA(self):
result = df.replace({r"^#": "$"}, regex=True)
expected = pd.Series([pd.NA, pd.NA])
tm.assert_series_equal(result, expected)


def test_replace_from_index():
# https://github.com/pandas-dev/pandas/issues/61622
idx = pd.Index(["a", "b", "c"], dtype="string[pyarrow]")
expected = pd.Series(["d", "b", "c"], dtype="string[pyarrow]")
result = pd.Series(idx).replace({"z": "b", "a": "d"})
tm.assert_series_equal(result, expected)
Loading