Skip to content

Commit 5a96329

Browse files
phoflmroeschke
authored andcommitted
DEPR: Deprecate remaining copy usages (#57870)
* DEPR: Deprecate remaining copy usages * Fixup * Fixup tests * Fixup tests --------- Co-authored-by: Matthew Roeschke <[email protected]>
1 parent cac615c commit 5a96329

File tree

19 files changed

+194
-98
lines changed

19 files changed

+194
-98
lines changed

doc/source/whatsnew/v3.0.0.rst

+7
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,13 @@ will be removed in a future version:
173173
- :meth:`DataFrame.astype` / :meth:`Series.astype`
174174
- :meth:`DataFrame.reindex` / :meth:`Series.reindex`
175175
- :meth:`DataFrame.reindex_like` / :meth:`Series.reindex_like`
176+
- :meth:`DataFrame.set_axis` / :meth:`Series.set_axis`
177+
- :meth:`DataFrame.to_period` / :meth:`Series.to_period`
178+
- :meth:`DataFrame.to_timestamp` / :meth:`Series.to_timestamp`
179+
- :meth:`DataFrame.rename` / :meth:`Series.rename`
180+
- :meth:`DataFrame.transpose`
181+
- :meth:`DataFrame.swaplevel`
182+
- :meth:`DataFrame.merge` / :func:`pd.merge`
176183

177184
Copy-on-Write utilizes a lazy copy mechanism that defers copying the data until
178185
necessary. Use ``.copy`` to trigger an eager copy. The copy keyword has no effect

pandas/core/frame.py

+37-14
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@
357357
of a string to indicate that the column name from `left` or
358358
`right` should be left as-is, with no suffix. At least one of the
359359
values must not be None.
360-
copy : bool, default True
360+
copy : bool, default False
361361
If False, avoid copy if possible.
362362
363363
.. note::
@@ -371,6 +371,8 @@
371371
372372
You can already get the future behavior and improvements through
373373
enabling copy on write ``pd.options.mode.copy_on_write = True``
374+
375+
.. deprecated:: 3.0.0
374376
indicator : bool or str, default False
375377
If True, adds a column to the output DataFrame called "_merge" with
376378
information on the source of each row. The column can be given a different
@@ -3576,7 +3578,11 @@ def memory_usage(self, index: bool = True, deep: bool = False) -> Series:
35763578
result = index_memory_usage._append(result)
35773579
return result
35783580

3579-
def transpose(self, *args, copy: bool = False) -> DataFrame:
3581+
def transpose(
3582+
self,
3583+
*args,
3584+
copy: bool | lib.NoDefault = lib.no_default,
3585+
) -> DataFrame:
35803586
"""
35813587
Transpose index and columns.
35823588
@@ -3607,6 +3613,8 @@ def transpose(self, *args, copy: bool = False) -> DataFrame:
36073613
You can already get the future behavior and improvements through
36083614
enabling copy on write ``pd.options.mode.copy_on_write = True``
36093615
3616+
.. deprecated:: 3.0.0
3617+
36103618
Returns
36113619
-------
36123620
DataFrame
@@ -3687,6 +3695,7 @@ def transpose(self, *args, copy: bool = False) -> DataFrame:
36873695
1 object
36883696
dtype: object
36893697
"""
3698+
self._check_copy_deprecation(copy)
36903699
nv.validate_transpose(args, {})
36913700
# construct the args
36923701

@@ -5062,9 +5071,9 @@ def set_axis(
50625071
labels,
50635072
*,
50645073
axis: Axis = 0,
5065-
copy: bool | None = None,
5074+
copy: bool | lib.NoDefault = lib.no_default,
50665075
) -> DataFrame:
5067-
return super().set_axis(labels, axis=axis)
5076+
return super().set_axis(labels, axis=axis, copy=copy)
50685077

50695078
@doc(
50705079
NDFrame.reindex,
@@ -5313,7 +5322,7 @@ def rename(
53135322
index: Renamer | None = ...,
53145323
columns: Renamer | None = ...,
53155324
axis: Axis | None = ...,
5316-
copy: bool | None = ...,
5325+
copy: bool | lib.NoDefault = lib.no_default,
53175326
inplace: Literal[True],
53185327
level: Level = ...,
53195328
errors: IgnoreRaise = ...,
@@ -5327,7 +5336,7 @@ def rename(
53275336
index: Renamer | None = ...,
53285337
columns: Renamer | None = ...,
53295338
axis: Axis | None = ...,
5330-
copy: bool | None = ...,
5339+
copy: bool | lib.NoDefault = lib.no_default,
53315340
inplace: Literal[False] = ...,
53325341
level: Level = ...,
53335342
errors: IgnoreRaise = ...,
@@ -5341,7 +5350,7 @@ def rename(
53415350
index: Renamer | None = ...,
53425351
columns: Renamer | None = ...,
53435352
axis: Axis | None = ...,
5344-
copy: bool | None = ...,
5353+
copy: bool | lib.NoDefault = lib.no_default,
53455354
inplace: bool = ...,
53465355
level: Level = ...,
53475356
errors: IgnoreRaise = ...,
@@ -5354,7 +5363,7 @@ def rename(
53545363
index: Renamer | None = None,
53555364
columns: Renamer | None = None,
53565365
axis: Axis | None = None,
5357-
copy: bool | None = None,
5366+
copy: bool | lib.NoDefault = lib.no_default,
53585367
inplace: bool = False,
53595368
level: Level | None = None,
53605369
errors: IgnoreRaise = "ignore",
@@ -5384,7 +5393,7 @@ def rename(
53845393
axis : {0 or 'index', 1 or 'columns'}, default 0
53855394
Axis to target with ``mapper``. Can be either the axis name
53865395
('index', 'columns') or number (0, 1). The default is 'index'.
5387-
copy : bool, default True
5396+
copy : bool, default False
53885397
Also copy underlying data.
53895398
53905399
.. note::
@@ -5398,6 +5407,8 @@ def rename(
53985407
53995408
You can already get the future behavior and improvements through
54005409
enabling copy on write ``pd.options.mode.copy_on_write = True``
5410+
5411+
.. deprecated:: 3.0.0
54015412
inplace : bool, default False
54025413
Whether to modify the DataFrame rather than creating a new one.
54035414
If True then value of copy is ignored.
@@ -5478,6 +5489,7 @@ def rename(
54785489
2 2 5
54795490
4 3 6
54805491
"""
5492+
self._check_copy_deprecation(copy)
54815493
return super()._rename(
54825494
mapper=mapper,
54835495
index=index,
@@ -10657,10 +10669,12 @@ def merge(
1065710669
right_index: bool = False,
1065810670
sort: bool = False,
1065910671
suffixes: Suffixes = ("_x", "_y"),
10660-
copy: bool | None = None,
10672+
copy: bool | lib.NoDefault = lib.no_default,
1066110673
indicator: str | bool = False,
1066210674
validate: MergeValidate | None = None,
1066310675
) -> DataFrame:
10676+
self._check_copy_deprecation(copy)
10677+
1066410678
from pandas.core.reshape.merge import merge
1066510679

1066610680
return merge(
@@ -12462,7 +12476,7 @@ def to_timestamp(
1246212476
freq: Frequency | None = None,
1246312477
how: ToTimestampHow = "start",
1246412478
axis: Axis = 0,
12465-
copy: bool | None = None,
12479+
copy: bool | lib.NoDefault = lib.no_default,
1246612480
) -> DataFrame:
1246712481
"""
1246812482
Cast to DatetimeIndex of timestamps, at *beginning* of period.
@@ -12476,7 +12490,7 @@ def to_timestamp(
1247612490
vs. end.
1247712491
axis : {0 or 'index', 1 or 'columns'}, default 0
1247812492
The axis to convert (the index by default).
12479-
copy : bool, default True
12493+
copy : bool, default False
1248012494
If False then underlying input data is not copied.
1248112495
1248212496
.. note::
@@ -12491,6 +12505,8 @@ def to_timestamp(
1249112505
You can already get the future behavior and improvements through
1249212506
enabling copy on write ``pd.options.mode.copy_on_write = True``
1249312507
12508+
.. deprecated:: 3.0.0
12509+
1249412510
Returns
1249512511
-------
1249612512
DataFrame
@@ -12527,6 +12543,7 @@ def to_timestamp(
1252712543
>>> df2.index
1252812544
DatetimeIndex(['2023-01-31', '2024-01-31'], dtype='datetime64[ns]', freq=None)
1252912545
"""
12546+
self._check_copy_deprecation(copy)
1253012547
new_obj = self.copy(deep=False)
1253112548

1253212549
axis_name = self._get_axis_name(axis)
@@ -12540,7 +12557,10 @@ def to_timestamp(
1254012557
return new_obj
1254112558

1254212559
def to_period(
12543-
self, freq: Frequency | None = None, axis: Axis = 0, copy: bool | None = None
12560+
self,
12561+
freq: Frequency | None = None,
12562+
axis: Axis = 0,
12563+
copy: bool | lib.NoDefault = lib.no_default,
1254412564
) -> DataFrame:
1254512565
"""
1254612566
Convert DataFrame from DatetimeIndex to PeriodIndex.
@@ -12554,7 +12574,7 @@ def to_period(
1255412574
Frequency of the PeriodIndex.
1255512575
axis : {0 or 'index', 1 or 'columns'}, default 0
1255612576
The axis to convert (the index by default).
12557-
copy : bool, default True
12577+
copy : bool, default False
1255812578
If False then underlying input data is not copied.
1255912579
1256012580
.. note::
@@ -12569,6 +12589,8 @@ def to_period(
1256912589
You can already get the future behavior and improvements through
1257012590
enabling copy on write ``pd.options.mode.copy_on_write = True``
1257112591
12592+
.. deprecated:: 3.0.0
12593+
1257212594
Returns
1257312595
-------
1257412596
DataFrame
@@ -12596,6 +12618,7 @@ def to_period(
1259612618
>>> idx.to_period("Y")
1259712619
PeriodIndex(['2001', '2002', '2003'], dtype='period[Y-DEC]')
1259812620
"""
12621+
self._check_copy_deprecation(copy)
1259912622
new_obj = self.copy(deep=False)
1260012623

1260112624
axis_name = self._get_axis_name(axis)

pandas/core/generic.py

+18-13
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ def flags(self) -> Flags:
398398
def set_flags(
399399
self,
400400
*,
401-
copy: bool = False,
401+
copy: bool | lib.NoDefault = lib.no_default,
402402
allows_duplicate_labels: bool | None = None,
403403
) -> Self:
404404
"""
@@ -420,6 +420,8 @@ def set_flags(
420420
421421
You can already get the future behavior and improvements through
422422
enabling copy on write ``pd.options.mode.copy_on_write = True``
423+
424+
.. deprecated:: 3.0.0
423425
allows_duplicate_labels : bool, optional
424426
Whether the returned object allows duplicate labels.
425427
@@ -454,6 +456,7 @@ def set_flags(
454456
>>> df2.flags.allows_duplicate_labels
455457
False
456458
"""
459+
self._check_copy_deprecation(copy)
457460
df = self.copy(deep=False)
458461
if allows_duplicate_labels is not None:
459462
df.flags["allows_duplicate_labels"] = allows_duplicate_labels
@@ -679,7 +682,7 @@ def set_axis(
679682
labels,
680683
*,
681684
axis: Axis = 0,
682-
copy: bool | None = None,
685+
copy: bool | lib.NoDefault = lib.no_default,
683686
) -> Self:
684687
"""
685688
Assign desired index to given axis.
@@ -696,7 +699,7 @@ def set_axis(
696699
The axis to update. The value 0 identifies the rows. For `Series`
697700
this parameter is unused and defaults to 0.
698701
699-
copy : bool, default True
702+
copy : bool, default False
700703
Whether to make a copy of the underlying data.
701704
702705
.. note::
@@ -711,6 +714,8 @@ def set_axis(
711714
You can already get the future behavior and improvements through
712715
enabling copy on write ``pd.options.mode.copy_on_write = True``
713716
717+
.. deprecated:: 3.0.0
718+
714719
Returns
715720
-------
716721
%(klass)s
@@ -720,6 +725,7 @@ def set_axis(
720725
--------
721726
%(klass)s.rename_axis : Alter the name of the index%(see_also_sub)s.
722727
"""
728+
self._check_copy_deprecation(copy)
723729
return self._set_axis_nocheck(labels, axis, inplace=False)
724730

725731
@overload
@@ -948,7 +954,6 @@ def _rename(
948954
index: Renamer | None = ...,
949955
columns: Renamer | None = ...,
950956
axis: Axis | None = ...,
951-
copy: bool | None = ...,
952957
inplace: Literal[False] = ...,
953958
level: Level | None = ...,
954959
errors: str = ...,
@@ -962,7 +967,6 @@ def _rename(
962967
index: Renamer | None = ...,
963968
columns: Renamer | None = ...,
964969
axis: Axis | None = ...,
965-
copy: bool | None = ...,
966970
inplace: Literal[True],
967971
level: Level | None = ...,
968972
errors: str = ...,
@@ -976,7 +980,6 @@ def _rename(
976980
index: Renamer | None = ...,
977981
columns: Renamer | None = ...,
978982
axis: Axis | None = ...,
979-
copy: bool | None = ...,
980983
inplace: bool,
981984
level: Level | None = ...,
982985
errors: str = ...,
@@ -990,7 +993,6 @@ def _rename(
990993
index: Renamer | None = None,
991994
columns: Renamer | None = None,
992995
axis: Axis | None = None,
993-
copy: bool | None = None,
994996
inplace: bool = False,
995997
level: Level | None = None,
996998
errors: str = "ignore",
@@ -1061,7 +1063,7 @@ def rename_axis(
10611063
index=...,
10621064
columns=...,
10631065
axis: Axis = ...,
1064-
copy: bool | None = ...,
1066+
copy: bool | lib.NoDefault = lib.no_default,
10651067
inplace: Literal[False] = ...,
10661068
) -> Self: ...
10671069

@@ -1073,7 +1075,7 @@ def rename_axis(
10731075
index=...,
10741076
columns=...,
10751077
axis: Axis = ...,
1076-
copy: bool | None = ...,
1078+
copy: bool | lib.NoDefault = lib.no_default,
10771079
inplace: Literal[True],
10781080
) -> None: ...
10791081

@@ -1085,7 +1087,7 @@ def rename_axis(
10851087
index=...,
10861088
columns=...,
10871089
axis: Axis = ...,
1088-
copy: bool | None = ...,
1090+
copy: bool | lib.NoDefault = lib.no_default,
10891091
inplace: bool = ...,
10901092
) -> Self | None: ...
10911093

@@ -1096,7 +1098,7 @@ def rename_axis(
10961098
index=lib.no_default,
10971099
columns=lib.no_default,
10981100
axis: Axis = 0,
1099-
copy: bool | None = None,
1101+
copy: bool | lib.NoDefault = lib.no_default,
11001102
inplace: bool = False,
11011103
) -> Self | None:
11021104
"""
@@ -1118,7 +1120,7 @@ def rename_axis(
11181120
apply to that axis' values.
11191121
axis : {0 or 'index', 1 or 'columns'}, default 0
11201122
The axis to rename.
1121-
copy : bool, default None
1123+
copy : bool, default False
11221124
Also copy underlying data.
11231125
11241126
.. note::
@@ -1132,6 +1134,8 @@ def rename_axis(
11321134
11331135
You can already get the future behavior and improvements through
11341136
enabling copy on write ``pd.options.mode.copy_on_write = True``
1137+
1138+
.. deprecated:: 3.0.0
11351139
inplace : bool, default False
11361140
Modifies the object directly, instead of creating a new Series
11371141
or DataFrame.
@@ -1219,6 +1223,7 @@ class name
12191223
cat 4 0
12201224
monkey 2 2
12211225
"""
1226+
self._check_copy_deprecation(copy)
12221227
axes = {"index": index, "columns": columns}
12231228

12241229
if axis is not None:
@@ -6327,7 +6332,7 @@ def astype(
63276332
return self.copy(deep=False)
63286333

63296334
# GH 19920: retain column metadata after concat
6330-
result = concat(results, axis=1, copy=False)
6335+
result = concat(results, axis=1)
63316336
# GH#40810 retain subclass
63326337
# error: Incompatible types in assignment
63336338
# (expression has type "Self", variable has type "DataFrame")

pandas/core/interchange/dataframe.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def __init__(self, df: DataFrame, allow_copy: bool = True) -> None:
3333
Constructor - an instance of this (private) class is returned from
3434
`pd.DataFrame.__dataframe__`.
3535
"""
36-
self._df = df.rename(columns=str, copy=False)
36+
self._df = df.rename(columns=str)
3737
self._allow_copy = allow_copy
3838
for i, _col in enumerate(self._df.columns):
3939
rechunked = maybe_rechunk(self._df.iloc[:, i], allow_copy=allow_copy)

0 commit comments

Comments
 (0)