Skip to content

Commit 455c880

Browse files
authored
BUG/CoW: Series.rename not making a lazy copy when passed a scalar (#53189)
1 parent f80436d commit 455c880

File tree

4 files changed

+17
-6
lines changed

4 files changed

+17
-6
lines changed

Diff for: doc/source/whatsnew/v2.0.2.rst

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Bug fixes
3232
- Bug in :meth:`DataFrame.__getitem__` not preserving dtypes for :class:`MultiIndex` partial keys (:issue:`51895`)
3333
- Bug in :meth:`DataFrame.convert_dtypes` ignores ``convert_*`` keywords when set to False ``dtype_backend="pyarrow"`` (:issue:`52872`)
3434
- Bug in :meth:`Series.describe` treating pyarrow-backed timestamps and timedeltas as categorical data (:issue:`53001`)
35+
- Bug in :meth:`Series.rename` not making a lazy copy when Copy-on-Write is enabled when a scalar is passed to it (:issue:`52450`)
3536
- Bug in :meth:`pd.array` raising for ``NumPy`` array and ``pa.large_string`` or ``pa.large_binary`` (:issue:`52590`)
3637

3738

Diff for: pandas/core/series.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -1907,7 +1907,9 @@ def to_frame(self, name: Hashable = lib.no_default) -> DataFrame:
19071907
df = self._constructor_expanddim(mgr)
19081908
return df.__finalize__(self, method="to_frame")
19091909

1910-
def _set_name(self, name, inplace: bool = False) -> Series:
1910+
def _set_name(
1911+
self, name, inplace: bool = False, deep: bool | None = None
1912+
) -> Series:
19111913
"""
19121914
Set the Series name.
19131915
@@ -1916,9 +1918,11 @@ def _set_name(self, name, inplace: bool = False) -> Series:
19161918
name : str
19171919
inplace : bool
19181920
Whether to modify `self` directly or return a copy.
1921+
deep : bool|None, default None
1922+
Whether to do a deep copy, a shallow copy, or Copy on Write(None)
19191923
"""
19201924
inplace = validate_bool_kwarg(inplace, "inplace")
1921-
ser = self if inplace else self.copy()
1925+
ser = self if inplace else self.copy(deep and not using_copy_on_write())
19221926
ser.name = name
19231927
return ser
19241928

@@ -4580,7 +4584,7 @@ def rename(
45804584
index: Renamer | Hashable | None = None,
45814585
*,
45824586
axis: Axis | None = None,
4583-
copy: bool = True,
4587+
copy: bool | None = None,
45844588
inplace: bool = False,
45854589
level: Level | None = None,
45864590
errors: IgnoreRaise = "ignore",
@@ -4667,7 +4671,7 @@ def rename(
46674671
errors=errors,
46684672
)
46694673
else:
4670-
return self._set_name(index, inplace=inplace)
4674+
return self._set_name(index, inplace=inplace, deep=copy)
46714675

46724676
@Appender(
46734677
"""

Diff for: pandas/tests/copy_view/test_methods.py

+2
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ def test_methods_copy_keyword(
141141
"method",
142142
[
143143
lambda ser, copy: ser.rename(index={0: 100}, copy=copy),
144+
lambda ser, copy: ser.rename(None, copy=copy),
144145
lambda ser, copy: ser.reindex(index=ser.index, copy=copy),
145146
lambda ser, copy: ser.reindex_like(ser, copy=copy),
146147
lambda ser, copy: ser.align(ser, copy=copy)[0],
@@ -158,6 +159,7 @@ def test_methods_copy_keyword(
158159
lambda ser, copy: ser.set_flags(allows_duplicate_labels=False, copy=copy),
159160
],
160161
ids=[
162+
"rename (dict)",
161163
"rename",
162164
"reindex",
163165
"reindex_like",

Diff for: pandas/tests/frame/indexing/test_setitem.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ def test_frame_setitem_existing_datetime64_col_other_units(self, unit):
316316
df["dates"] = vals
317317
assert (df["dates"].values == ex_vals).all()
318318

319-
def test_setitem_dt64tz(self, timezone_frame):
319+
def test_setitem_dt64tz(self, timezone_frame, using_copy_on_write):
320320
df = timezone_frame
321321
idx = df["B"].rename("foo")
322322

@@ -331,12 +331,16 @@ def test_setitem_dt64tz(self, timezone_frame):
331331

332332
# assert that A & C are not sharing the same base (e.g. they
333333
# are copies)
334+
# Note: This does not hold with Copy on Write (because of lazy copying)
334335
v1 = df._mgr.arrays[1]
335336
v2 = df._mgr.arrays[2]
336337
tm.assert_extension_array_equal(v1, v2)
337338
v1base = v1._ndarray.base
338339
v2base = v2._ndarray.base
339-
assert v1base is None or (id(v1base) != id(v2base))
340+
if not using_copy_on_write:
341+
assert v1base is None or (id(v1base) != id(v2base))
342+
else:
343+
assert id(v1base) == id(v2base)
340344

341345
# with nan
342346
df2 = df.copy()

0 commit comments

Comments
 (0)