Skip to content

Commit 5718de1

Browse files
authored
ENH: add lazy copy (CoW) mechanism to rename_axis (#50415)
1 parent 98efdc8 commit 5718de1

File tree

2 files changed

+31
-5
lines changed

2 files changed

+31
-5
lines changed

pandas/core/generic.py

+12-5
Original file line numberDiff line numberDiff line change
@@ -1209,7 +1209,8 @@ class name
12091209
axes, kwargs = self._construct_axes_from_arguments(
12101210
(), kwargs, sentinel=lib.no_default
12111211
)
1212-
copy = kwargs.pop("copy", True)
1212+
copy: bool_t | None = kwargs.pop("copy", None)
1213+
12131214
inplace = kwargs.pop("inplace", False)
12141215
axis = kwargs.pop("axis", 0)
12151216
if axis is not None:
@@ -1229,7 +1230,9 @@ class name
12291230
is_list_like(mapper) and not is_dict_like(mapper)
12301231
)
12311232
if non_mapper:
1232-
return self._set_axis_name(mapper, axis=axis, inplace=inplace)
1233+
return self._set_axis_name(
1234+
mapper, axis=axis, inplace=inplace, copy=copy
1235+
)
12331236
else:
12341237
raise ValueError("Use `.rename` to alter labels with a mapper.")
12351238
else:
@@ -1248,13 +1251,15 @@ class name
12481251
f = common.get_rename_function(v)
12491252
curnames = self._get_axis(axis).names
12501253
newnames = [f(name) for name in curnames]
1251-
result._set_axis_name(newnames, axis=axis, inplace=True)
1254+
result._set_axis_name(newnames, axis=axis, inplace=True, copy=copy)
12521255
if not inplace:
12531256
return result
12541257
return None
12551258

12561259
@final
1257-
def _set_axis_name(self, name, axis: Axis = 0, inplace: bool_t = False):
1260+
def _set_axis_name(
1261+
self, name, axis: Axis = 0, inplace: bool_t = False, copy: bool_t | None = True
1262+
):
12581263
"""
12591264
Set the name(s) of the axis.
12601265
@@ -1267,6 +1272,8 @@ def _set_axis_name(self, name, axis: Axis = 0, inplace: bool_t = False):
12671272
and the value 1 or 'columns' specifies columns.
12681273
inplace : bool, default False
12691274
If `True`, do operation inplace and return None.
1275+
copy:
1276+
Whether to make a copy of the result.
12701277
12711278
Returns
12721279
-------
@@ -1308,7 +1315,7 @@ def _set_axis_name(self, name, axis: Axis = 0, inplace: bool_t = False):
13081315
idx = self._get_axis(axis).set_names(name)
13091316

13101317
inplace = validate_bool_kwarg(inplace, "inplace")
1311-
renamed = self if inplace else self.copy()
1318+
renamed = self if inplace else self.copy(deep=copy)
13121319
if axis == 0:
13131320
renamed.index = idx
13141321
else:

pandas/tests/copy_view/test_methods.py

+19
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
from pandas import (
55
DataFrame,
6+
Index,
67
MultiIndex,
78
Series,
89
)
@@ -456,3 +457,21 @@ def test_series_set_axis(using_copy_on_write):
456457
ser2.iloc[0] = 0
457458
assert not np.shares_memory(ser2, ser)
458459
tm.assert_series_equal(ser, ser_orig)
460+
461+
462+
@pytest.mark.parametrize("copy_kwargs", [{"copy": True}, {}])
463+
@pytest.mark.parametrize("kwargs", [{"mapper": "test"}, {"index": "test"}])
464+
def test_rename_axis(using_copy_on_write, kwargs, copy_kwargs):
465+
df = DataFrame({"a": [1, 2, 3, 4]}, index=Index([1, 2, 3, 4], name="a"))
466+
df_orig = df.copy()
467+
df2 = df.rename_axis(**kwargs, **copy_kwargs)
468+
469+
if using_copy_on_write and not copy_kwargs:
470+
assert np.shares_memory(get_array(df2, "a"), get_array(df, "a"))
471+
else:
472+
assert not np.shares_memory(get_array(df2, "a"), get_array(df, "a"))
473+
474+
df2.iloc[0, 0] = 0
475+
if using_copy_on_write:
476+
assert not np.shares_memory(get_array(df2, "a"), get_array(df, "a"))
477+
tm.assert_frame_equal(df, df_orig)

0 commit comments

Comments
 (0)