DOC: Update pandas.Series.copy docstring
State: closed

Closes https://github.com/pandas-dev/pandas/issues/19505

- Add extended summary
- Add examples

Checklist for the pandas documentation sprint (ignore this if you are doing
an unrelated PR):

- [X] PR title is "DOC: update the <your-function-or-method> docstring"
- [X] The validation script passes: `scripts/validate_docstrings.py <your-function-or-method>`
- [X] The PEP8 style check passes: `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [X] The html version looks good: `python doc/make.py --single <your-function-or-method>`
- [X] It has been proofread on language by another sprint participant

Please include the output of the validation script below between the "```" ticks:

```

################################################################################
######################## Docstring (pandas.Series.copy) ########################
################################################################################

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
----------
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.

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))

################################################################################
################################## Validation ##################################
################################################################################

Errors found:
        See Also section not found

```

If the validation script still gives errors, but you think there is a good reason
to deviate in this case (and there are certainly such cases), please state this
explicitly.

Not sure if anything should be added to the See Also section

Labels:
name: Docs

Comments:
I removed the wording/examples about the index not being copied when deep=False because while it's not copied when .copy() is called, if the index is changed on the shallow copy it does not affect the index of the original (in contrast with the data values, which are also not copied, but changes to values do affect the original).  
@thismakessand not sure I fully understand why you removed the mention of indices. Perhaps its related to the conversation in https://github.com/pandas-dev/pandas/issues/19862? Referencing that I think it's preferable to use `is` for comparing the indices instead of using the equality operator. Perhaps that will help clarify how the copy is actually working behind the scenes.

Lot's of edits but they are mostly minor - thanks and keep up the great work!
Thanks - I added more clarification regarding the index and made the examples simpler and hopefully clearer.
# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/20261?src=pr&el=h1) Report
> Merging [#20261](https://codecov.io/gh/pandas-dev/pandas/pull/20261?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/7273ea0709590e6264607f227bb8def0ef656c50?src=pr&el=desc) will **increase** coverage by `0.06%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/pandas-dev/pandas/pull/20261/graphs/tree.svg?width=650&src=pr&token=eZ4WkYLtcO&height=150)](https://codecov.io/gh/pandas-dev/pandas/pull/20261?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master   #20261      +/-   ##
==========================================
+ Coverage   91.77%   91.84%   +0.06%     
==========================================
  Files         152      152              
  Lines       49205    49231      +26     
==========================================
+ Hits        45159    45215      +56     
+ Misses       4046     4016      -30
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `90.22% <100%> (+0.06%)` | :arrow_up: |
| #single | `41.83% <33.33%> (-0.02%)` | :arrow_down: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/20261?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/core/generic.py](https://codecov.io/gh/pandas-dev/pandas/pull/20261/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZ2VuZXJpYy5weQ==) | `95.85% <100%> (ø)` | :arrow_up: |
| [pandas/core/arrays/categorical.py](https://codecov.io/gh/pandas-dev/pandas/pull/20261/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvYXJyYXlzL2NhdGVnb3JpY2FsLnB5) | `96.2% <0%> (-0.02%)` | :arrow_down: |
| [pandas/core/window.py](https://codecov.io/gh/pandas-dev/pandas/pull/20261/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvd2luZG93LnB5) | `96.26% <0%> (-0.01%)` | :arrow_down: |
| [pandas/core/indexes/datetimelike.py](https://codecov.io/gh/pandas-dev/pandas/pull/20261/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvaW5kZXhlcy9kYXRldGltZWxpa2UucHk=) | `96.72% <0%> (ø)` | :arrow_up: |
| [pandas/core/panel.py](https://codecov.io/gh/pandas-dev/pandas/pull/20261/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvcGFuZWwucHk=) | `97.29% <0%> (ø)` | :arrow_up: |
| [pandas/core/base.py](https://codecov.io/gh/pandas-dev/pandas/pull/20261/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvYmFzZS5weQ==) | `96.78% <0%> (ø)` | :arrow_up: |
| [pandas/core/indexes/category.py](https://codecov.io/gh/pandas-dev/pandas/pull/20261/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvaW5kZXhlcy9jYXRlZ29yeS5weQ==) | `97.3% <0%> (ø)` | :arrow_up: |
| [pandas/core/series.py](https://codecov.io/gh/pandas-dev/pandas/pull/20261/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvc2VyaWVzLnB5) | `93.84% <0%> (ø)` | :arrow_up: |
| [pandas/core/frame.py](https://codecov.io/gh/pandas-dev/pandas/pull/20261/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZnJhbWUucHk=) | `97.18% <0%> (ø)` | :arrow_up: |
| ... and [9 more](https://codecov.io/gh/pandas-dev/pandas/pull/20261/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/20261?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/20261?src=pr&el=footer). Last update [7273ea0...18c7be3](https://codecov.io/gh/pandas-dev/pandas/pull/20261?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

@thismakessand Do you have time to update this PR based on the remaining feedback ?
@jorisvandenbossche Yes, it's definitely still on my radar, hoping to find some time later today or tomorrow.
I read through the linked issues and added the details you mentioned.  Looking at the linked issues and other stuff on stack overflow, etc it seems like most of the confusion is around 
1. deep copy not being a "true" deep copy when the series/dataframe contains python objects and 
2. the underlying data of the Index isn't copied even when deep=True. 

I think both of these are covered now.  Originally I had more details but  I was worried going too into the caveats would just be unnecessarily confusing so I cut a bit out.  I can add more if it's still unclear. 
@thismakessand Thanks a lot!
There is one remaining thing: the type description for `deep` also said 'str'. I removed this for now, as it is not explained, but apparently `'all'` is accepted to also copy the Index underlying data. 
But will open a new issue for that to see if we actually want to expose this publicly.