From 2686324c39c4835bb79c5544ab8edf918f0895c9 Mon Sep 17 00:00:00 2001 From: "jennifer.weiss" Date: Sat, 10 Mar 2018 17:01:03 -0600 Subject: [PATCH 1/6] DOC: Update pandas.Series.copy docstring - Add extended summary - Add examples --- pandas/core/generic.py | 106 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index d5bdeb7fe1a4d..fc6238727349b 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -4506,7 +4506,15 @@ def astype(self, dtype, copy=True, errors='raise', **kwargs): def copy(self, deep=True): """ - Make a copy of this objects data. + Make a copy of this objects indices and data. + + Deep copy (default) will create a new object with a copy of the objects + data and indices. Modifications to the data or indices of the copy + will not be reflected in the original object. + + Shallow copy (``deep=False``) will create a new object without copying + the data or indices. Any changes to the index or data of the original + will be reflected in the shallow copy (and vice versa). Parameters ---------- @@ -4522,6 +4530,102 @@ def copy(self, deep=True): Returns ------- copy : type of caller + + Examples + -------- + >>> s = pd.Series([1,2], dtype="int32", index=["a", "b"]) + >>> s + a 1 + b 2 + dtype: int32 + >>> s_copy = s.copy() + >>> s_copy + a 1 + b 2 + dtype: int32 + + Shallow copy versus default (deep) copy: + + In a shallow copy the index and data is a reference to the original + objects'. + + >>> s = pd.Series([1,2], dtype="int32", index=["a", "b"]) + >>> deep_copy = s.copy() + >>> shallow_copy = s.copy(deep=False) + >>> id(s) == id(shallow_copy) + False + >>> id(s.index) == id(shallow_copy.index) + True + >>> id(s.values) == id(shallow_copy.values) + True + >>> id(s) == id(deep_copy) + False + >>> id(s.index) == id(deep_copy.index) + False + >>> id(s.values) == id(deep_copy.values) + False + >>> s[0] = 3 + >>> s + a 3 + b 2 + dtype: int32 + >>> shallow_copy + a 3 + b 2 + dtype: int32 + >>> deep_copy + a 1 + b 2 + dtype: int32 + >>> shallow_copy[0] = 4 + >>> s + a 4 + b 2 + dtype: int32 + >>> shallow_copy + a 4 + b 2 + dtype: int32 + >>> deep_copy + a 1 + b 2 + dtype: int32 + + When copying object containing python objects, deep copy will + copy the indices and data but will not do so recursively. + + >>> class Point(object): + ... def __init__(self, x, y): + ... self.x = x + ... self.y = y + ... def __repr__(self): + ... return "Point(%d,%d)" % (self.x, self.y) + ... + >>> p1 = Point(0, 1) + >>> s = pd.Series([p1], dtype="object") + >>> s + 0 Point(0,1) + dtype: object + >>> s_copy = s.copy() + >>> s_copy + 0 Point(0,1) + dtype: object + >>> id(s[0]) == id(s_copy[0]) + True + >>> p1.x = 1 + >>> s + 0 Point(1,1) + dtype: object + >>> s_copy + 0 Point(1,1) + dtype: object + >>> + + For deep-copying python objects, the following can be used: + + >>> import copy + >>> deep_deep_copy = pd.Series(copy.deepcopy(s.values), + ... index=copy.deepcopy(s.index)) """ data = self._data.copy(deep=deep) return self._constructor(data).__finalize__(self) From 582f047e431ef565c861c0c0da48a7849d17232a Mon Sep 17 00:00:00 2001 From: "jennifer.weiss" Date: Sat, 10 Mar 2018 21:13:32 -0600 Subject: [PATCH 2/6] Simplifying examples; adding Notes section --- pandas/core/generic.py | 88 +++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 52 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index fc6238727349b..b0116b48618d8 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -4506,120 +4506,104 @@ def astype(self, dtype, copy=True, errors='raise', **kwargs): def copy(self, deep=True): """ - Make a copy of this objects indices and data. + Make a copy of this object's indices and data. - Deep copy (default) will create a new object with a copy of the objects - data and indices. Modifications to the data or indices of the copy - will not be reflected in the original object. + When `deep=True` (default), a new object will be created with a + copy of the calling object's data and indices. Modifications to + the data or indices of the copy will not be reflected in the + original object (see notes below). - Shallow copy (``deep=False``) will create a new object without copying - the data or indices. Any changes to the index or data of the original - will be reflected in the shallow copy (and vice versa). + When `deep=False`, a new object will be created without copying + the calling object's data (only a reference to the data is + copied). Any changes to the data of the original will be reflected + in the shallow copy (and vice versa). Parameters ---------- deep : boolean or string, default True Make a deep copy, including a copy of the data and the indices. - With ``deep=False`` neither the indices or the data are copied. - - Note that when ``deep=True`` data is copied, actual python objects - will not be copied recursively, only the reference to the object. - This is in contrast to ``copy.deepcopy`` in the Standard Library, - which recursively copies object data. + With `deep=False` neither the indices or the data are copied. Returns ------- copy : type of caller + Notes + ----- + When `deep=True`, data is copied but actual python objects + will not be copied recursively, only the reference to the object. + This is in contrast to `copy.deepcopy` in the Standard Library, + which recursively copies object data. (See examples below). + Examples -------- - >>> s = pd.Series([1,2], dtype="int32", index=["a", "b"]) + >>> s = pd.Series([1, 2], index=["a", "b"]) >>> s a 1 b 2 - dtype: int32 + dtype: int64 >>> s_copy = s.copy() >>> s_copy a 1 b 2 - dtype: int32 + dtype: int64 Shallow copy versus default (deep) copy: - In a shallow copy the index and data is a reference to the original - objects'. + In a shallow copy, the data is shared with the original object. - >>> s = pd.Series([1,2], dtype="int32", index=["a", "b"]) + >>> s = pd.Series([1,2], index=["a", "b"]) >>> deep_copy = s.copy() >>> shallow_copy = s.copy(deep=False) >>> id(s) == id(shallow_copy) False - >>> id(s.index) == id(shallow_copy.index) - True >>> id(s.values) == id(shallow_copy.values) True >>> id(s) == id(deep_copy) False - >>> id(s.index) == id(deep_copy.index) - False >>> id(s.values) == id(deep_copy.values) False >>> s[0] = 3 >>> s a 3 b 2 - dtype: int32 + dtype: int64 >>> shallow_copy a 3 b 2 - dtype: int32 + dtype: int64 >>> deep_copy a 1 b 2 - dtype: int32 + dtype: int64 >>> shallow_copy[0] = 4 >>> s a 4 b 2 - dtype: int32 + dtype: int64 >>> shallow_copy a 4 b 2 - dtype: int32 + dtype: int64 >>> deep_copy a 1 b 2 - dtype: int32 + dtype: int64 - When copying object containing python objects, deep copy will - copy the indices and data but will not do so recursively. + When copying an object containing python objects, deep copy will + copy the data, but will not do so recursively. - >>> class Point(object): - ... def __init__(self, x, y): - ... self.x = x - ... self.y = y - ... def __repr__(self): - ... return "Point(%d,%d)" % (self.x, self.y) - ... - >>> p1 = Point(0, 1) - >>> s = pd.Series([p1], dtype="object") - >>> s - 0 Point(0,1) - dtype: object + >>> s = pd.Series([[1, 2], [3, 4]]) >>> s_copy = s.copy() - >>> s_copy - 0 Point(0,1) - dtype: object - >>> id(s[0]) == id(s_copy[0]) - True - >>> p1.x = 1 + >>> s[0][0] = 10 >>> s - 0 Point(1,1) + 0 [10, 2] + 1 [3, 4] dtype: object >>> s_copy - 0 Point(1,1) + 0 [10, 2] + 1 [3, 4] dtype: object - >>> For deep-copying python objects, the following can be used: From f1560e13d38ef7b3d5c8b22eda28329948430680 Mon Sep 17 00:00:00 2001 From: "jennifer.weiss" Date: Sun, 11 Mar 2018 22:19:59 -0500 Subject: [PATCH 3/6] Add details regarding handling of index and streamline examples --- pandas/core/generic.py | 80 +++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 43 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index b0116b48618d8..b0ce937870db9 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -4514,26 +4514,28 @@ def copy(self, deep=True): original object (see notes below). When `deep=False`, a new object will be created without copying - the calling object's data (only a reference to the data is - copied). Any changes to the data of the original will be reflected - in the shallow copy (and vice versa). + the calling object's data or index (only references to the data + and index are copied). Any changes to the data of the original + will be reflected in the shallow copy (and vice versa). Changes + to the index will result in a new index as indices are immutable. Parameters ---------- - deep : boolean or string, default True + deep : boolean or str, default `True` Make a deep copy, including a copy of the data and the indices. - With `deep=False` neither the indices or the data are copied. + With `deep=False` neither the indices nor the data are copied. Returns ------- copy : type of caller + Object type matches caller. Notes ----- - When `deep=True`, data is copied but actual python objects + When `deep=True`, data is copied but actual Python objects will not be copied recursively, only the reference to the object. This is in contrast to `copy.deepcopy` in the Standard Library, - which recursively copies object data. (See examples below). + which recursively copies object data (see examples below). Examples -------- @@ -4542,74 +4544,66 @@ def copy(self, deep=True): a 1 b 2 dtype: int64 + >>> s_copy = s.copy() >>> s_copy a 1 b 2 dtype: int64 - Shallow copy versus default (deep) copy: + **Shallow copy versus default (deep) copy:** + + >>> s = pd.Series([1, 2], index=["a", "b"]) + >>> deep = s.copy() + >>> shallow = s.copy(deep=False) - In a shallow copy, the data is shared with the original object. + Shallow copy shares data and index with original. - >>> s = pd.Series([1,2], index=["a", "b"]) - >>> deep_copy = s.copy() - >>> shallow_copy = s.copy(deep=False) - >>> id(s) == id(shallow_copy) + >>> s is shallow False - >>> id(s.values) == id(shallow_copy.values) + >>> s.values is shallow.values and s.index is shallow.index True - >>> id(s) == id(deep_copy) + + Deep copy has own copy of data and index. + + >>> s is deep False - >>> id(s.values) == id(deep_copy.values) + >>> s.values is deep.values or s.index is deep.index False + + Updates to the data shared by shallow copy and original is reflected + in both; deep copy remains unchanged. + >>> s[0] = 3 + >>> shallow[1] = 4 >>> s a 3 - b 2 + b 4 dtype: int64 - >>> shallow_copy + >>> shallow a 3 - b 2 + b 4 dtype: int64 - >>> deep_copy - a 1 - b 2 - dtype: int64 - >>> shallow_copy[0] = 4 - >>> s - a 4 - b 2 - dtype: int64 - >>> shallow_copy - a 4 - b 2 - dtype: int64 - >>> deep_copy + >>> deep a 1 b 2 dtype: int64 - When copying an object containing python objects, deep copy will - copy the data, but will not do so recursively. + When copying an object containing Python objects, a deep copy will + copy the data, but will not do so recursively. Updating a nested data + object will be reflected in the deep copy. >>> s = pd.Series([[1, 2], [3, 4]]) - >>> s_copy = s.copy() + >>> deep = s.copy() >>> s[0][0] = 10 >>> s 0 [10, 2] 1 [3, 4] dtype: object - >>> s_copy + >>> deep 0 [10, 2] 1 [3, 4] dtype: object - - For deep-copying python objects, the following can be used: - - >>> import copy - >>> deep_deep_copy = pd.Series(copy.deepcopy(s.values), - ... index=copy.deepcopy(s.index)) """ data = self._data.copy(deep=deep) return self._constructor(data).__finalize__(self) From c4aed31f2d6ded545a461176683c592a21ec5328 Mon Sep 17 00:00:00 2001 From: "jennifer.weiss" Date: Mon, 12 Mar 2018 13:37:31 -0500 Subject: [PATCH 4/6] Update Returns section to list types of objects --- pandas/core/generic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index b0ce937870db9..8245a19fefe01 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -4527,7 +4527,7 @@ def copy(self, deep=True): Returns ------- - copy : type of caller + copy : Series, DataFrame or Panel Object type matches caller. Notes From 541edc29ef880a574c4d391e0c412b3a1d536936 Mon Sep 17 00:00:00 2001 From: "jennifer.weiss" Date: Thu, 22 Mar 2018 21:26:55 -0500 Subject: [PATCH 5/6] Additional details on index handling --- pandas/core/generic.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 8245a19fefe01..1e3885a8555ac 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -4516,8 +4516,7 @@ def copy(self, deep=True): When `deep=False`, a new object will be created without copying the calling object's data or index (only references to the data and index are copied). Any changes to the data of the original - will be reflected in the shallow copy (and vice versa). Changes - to the index will result in a new index as indices are immutable. + will be reflected in the shallow copy (and vice versa). Parameters ---------- @@ -4532,11 +4531,16 @@ def copy(self, deep=True): Notes ----- - When `deep=True`, data is copied but actual Python objects + When ``deep=True``, data is copied but actual Python objects will not be copied recursively, only the reference to the object. This is in contrast to `copy.deepcopy` in the Standard Library, which recursively copies object data (see examples below). + While ``Index`` objects are copied when ``deep=True``, the underlying + numpy array is not copied for performance reasons. Since ``Index`` is + immutable, the underlying data can be safely shared and a copy + is not needed. + Examples -------- >>> s = pd.Series([1, 2], index=["a", "b"]) @@ -4589,9 +4593,9 @@ def copy(self, deep=True): b 2 dtype: int64 - When copying an object containing Python objects, a deep copy will - copy the data, but will not do so recursively. Updating a nested data - object will be reflected in the deep copy. + Note that when copying an object containing Python objects, a deep copy + will copy the data, but will not do so recursively. Updating a nested + data object will be reflected in the deep copy. >>> s = pd.Series([[1, 2], [3, 4]]) >>> deep = s.copy() From 18c7be3e60b2025aee8e64cca4224c1cf5fd0e5d Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Fri, 23 Mar 2018 09:49:54 +0100 Subject: [PATCH 6/6] Update generic.py --- pandas/core/generic.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 1e3885a8555ac..a65c2cd8df350 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -4508,21 +4508,21 @@ def copy(self, deep=True): """ Make a copy of this object's indices and data. - When `deep=True` (default), a new object will be created with a + When ``deep=True`` (default), a new object will be created with a copy of the calling object's data and indices. Modifications to the data or indices of the copy will not be reflected in the original object (see notes below). - When `deep=False`, a new object will be created without copying + When ``deep=False``, a new object will be created without copying the calling object's data or index (only references to the data and index are copied). Any changes to the data of the original will be reflected in the shallow copy (and vice versa). Parameters ---------- - deep : boolean or str, default `True` + deep : bool, default True Make a deep copy, including a copy of the data and the indices. - With `deep=False` neither the indices nor the data are copied. + With ``deep=False`` neither the indices nor the data are copied. Returns -------