DOC: Generalize "rename" documentation
State: closed

In this pull request, the documentation of the rename function of NDFrame is generalized over all its children using the function: DataFrame, Series and Panel. These three classes now use the Substitute decorator to add the generic part of the documentation to their own, using the same decorator to replace class specific parameters into the generic documentation.

I have tried my best to create as little changes to the documentation of each individual function. Although I have tried to get rid of all style errors, I do still receive some errors from the `validate_docstrings.py`:

```
Series
2 Errors found:
	Parameters {**kwargs} not documented
	Unknown parameters {errors, copy, inplace, level}
```

```
Panel
2 Errors found:
	Parameters {minor_axis, items, **kwargs, major_axis} not documented
	Unknown parameters {items, major_axis, minor_axis, copy, errors, inplace, level}
```

Help is appreciated!

Labels:
name: Docs

Comments:
# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/25577?src=pr&el=h1) Report
> Merging [#25577](https://codecov.io/gh/pandas-dev/pandas/pull/25577?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/3e652ac565e054b763ccbe23006c02704f6cd1b1?src=pr&el=desc) will **increase** coverage by `<.01%`.
> The diff coverage is `100%`.

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

```diff
@@            Coverage Diff             @@
##           master   #25577      +/-   ##
==========================================
+ Coverage   91.26%   91.26%   +<.01%     
==========================================
  Files         173      173              
  Lines       52966    52970       +4     
==========================================
+ Hits        48337    48342       +5     
+ Misses       4629     4628       -1
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `89.83% <100%> (ø)` | :arrow_up: |
| #single | `41.71% <100%> (-0.01%)` | :arrow_down: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/25577?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/core/generic.py](https://codecov.io/gh/pandas-dev/pandas/pull/25577/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZ2VuZXJpYy5weQ==) | `93.65% <ø> (ø)` | :arrow_up: |
| [pandas/core/frame.py](https://codecov.io/gh/pandas-dev/pandas/pull/25577/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZnJhbWUucHk=) | `96.79% <100%> (ø)` | :arrow_up: |
| [pandas/core/series.py](https://codecov.io/gh/pandas-dev/pandas/pull/25577/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvc2VyaWVzLnB5) | `93.69% <100%> (+0.01%)` | :arrow_up: |
| [pandas/core/panel.py](https://codecov.io/gh/pandas-dev/pandas/pull/25577/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvcGFuZWwucHk=) | `38.56% <100%> (ø)` | :arrow_up: |
| [pandas/util/testing.py](https://codecov.io/gh/pandas-dev/pandas/pull/25577/diff?src=pr&el=tree#diff-cGFuZGFzL3V0aWwvdGVzdGluZy5weQ==) | `87.66% <0%> (+0.09%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/25577?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/25577?src=pr&el=footer). Last update [3e652ac...6b489e4](https://codecov.io/gh/pandas-dev/pandas/pull/25577?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/25577?src=pr&el=h1) Report
> Merging [#25577](https://codecov.io/gh/pandas-dev/pandas/pull/25577?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/3e652ac565e054b763ccbe23006c02704f6cd1b1?src=pr&el=desc) will **increase** coverage by `<.01%`.
> The diff coverage is `100%`.

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

```diff
@@            Coverage Diff             @@
##           master   #25577      +/-   ##
==========================================
+ Coverage   91.26%   91.26%   +<.01%     
==========================================
  Files         173      173              
  Lines       52966    52970       +4     
==========================================
+ Hits        48337    48342       +5     
+ Misses       4629     4628       -1
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `89.83% <100%> (ø)` | :arrow_up: |
| #single | `41.71% <100%> (-0.01%)` | :arrow_down: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/25577?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/core/generic.py](https://codecov.io/gh/pandas-dev/pandas/pull/25577/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZ2VuZXJpYy5weQ==) | `93.65% <ø> (ø)` | :arrow_up: |
| [pandas/core/frame.py](https://codecov.io/gh/pandas-dev/pandas/pull/25577/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZnJhbWUucHk=) | `96.79% <100%> (ø)` | :arrow_up: |
| [pandas/core/series.py](https://codecov.io/gh/pandas-dev/pandas/pull/25577/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvc2VyaWVzLnB5) | `93.69% <100%> (+0.01%)` | :arrow_up: |
| [pandas/core/panel.py](https://codecov.io/gh/pandas-dev/pandas/pull/25577/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvcGFuZWwucHk=) | `38.56% <100%> (ø)` | :arrow_up: |
| [pandas/util/testing.py](https://codecov.io/gh/pandas-dev/pandas/pull/25577/diff?src=pr&el=tree#diff-cGFuZGFzL3V0aWwvdGVzdGluZy5weQ==) | `87.66% <0%> (+0.09%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/25577?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/25577?src=pr&el=footer). Last update [3e652ac...6b489e4](https://codecov.io/gh/pandas-dev/pandas/pull/25577?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/25577?src=pr&el=h1) Report
> Merging [#25577](https://codecov.io/gh/pandas-dev/pandas/pull/25577?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/f88613929d6c83952cb5a6bf70678a78be480baa?src=pr&el=desc) will **increase** coverage by `0.03%`.
> The diff coverage is `100%`.

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

```diff
@@            Coverage Diff             @@
##           master   #25577      +/-   ##
==========================================
+ Coverage   91.26%   91.29%   +0.03%     
==========================================
  Files         173      173              
  Lines       52968    52965       -3     
==========================================
+ Hits        48340    48354      +14     
+ Misses       4628     4611      -17
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `89.87% <100%> (+0.03%)` | :arrow_up: |
| #single | `41.73% <100%> (+0.02%)` | :arrow_up: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/25577?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/core/frame.py](https://codecov.io/gh/pandas-dev/pandas/pull/25577/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZnJhbWUucHk=) | `96.79% <100%> (ø)` | :arrow_up: |
| [pandas/core/series.py](https://codecov.io/gh/pandas-dev/pandas/pull/25577/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvc2VyaWVzLnB5) | `93.69% <100%> (+0.01%)` | :arrow_up: |
| [pandas/core/generic.py](https://codecov.io/gh/pandas-dev/pandas/pull/25577/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZ2VuZXJpYy5weQ==) | `93.65% <100%> (ø)` | :arrow_up: |
| [pandas/core/panel.py](https://codecov.io/gh/pandas-dev/pandas/pull/25577/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvcGFuZWwucHk=) | `38.56% <100%> (ø)` | :arrow_up: |
| [pandas/core/sorting.py](https://codecov.io/gh/pandas-dev/pandas/pull/25577/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvc29ydGluZy5weQ==) | `98.29% <0%> (+0.02%)` | :arrow_up: |
| [pandas/core/ops.py](https://codecov.io/gh/pandas-dev/pandas/pull/25577/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvb3BzLnB5) | `91.74% <0%> (+0.1%)` | :arrow_up: |
| [pandas/util/testing.py](https://codecov.io/gh/pandas-dev/pandas/pull/25577/diff?src=pr&el=tree#diff-cGFuZGFzL3V0aWwvdGVzdGluZy5weQ==) | `89.08% <0%> (+1.41%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/25577?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/25577?src=pr&el=footer). Last update [f886139...9053bac](https://codecov.io/gh/pandas-dev/pandas/pull/25577?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

From our conversation yesterday and from the code, you would think that indeed the `mapper`, `columns`, and `axis` parameters are allowed as well.

Upon further inspection, I did notice that they are indeed not disallowed. However, they do not seem to have the same behavior as the DataFrame counterparts:
```python
s = pd.Series([1,2,3,4])
df = pd.DataFrame([1,2,3,4])

s
0    1
1    2
2    3
3    4
dtype: int64

df
   0
0  1
1  2
2  3
3  4

s.rename(mapper={0:'x'}, axis=0)
0    1
1    2
2    3
3    4
dtype: int64

df.rename(mapper={0:'x'}, axis=0)
   0
x  1
1  2
2  3
3  4

s.rename(columns={"NONEXISTENT": 'a'}, errors="raise")
0    1
1    2
2    3
3    4
dtype: int64

df.rename(colums={"NONEXISTENT": 'a'}, errors="raise")
Traceback (most recent call last):
...
KeyError: "['NONEXISTENT'] not found in axis"

```

From this, I do not think it is a good decision to generalize the documentation over these arguments, as they do not provide the same functionality for Series and DataFrame. Generalizing the Series documentation to essentially the one of DataFrame, leads to a misleading documentation for Series.
Can you take a look at reindex? I think that has a similar issue from an API perspective but handles the docstring substitution in a way that requires less duplication
@WillAyd I have now tried to use the `_shared_doc_kwargs` together with a few additions:

- `altered`: To specify what is being altered
- `axes_alt_types`: To specify the alternative types of the axes, which are different for Series since it also includes the rename use of `Series.name`
- `alternative_use`: A string describing the above alternative use.

I have not found a way to effectively generalize the `mapper` parameter for DataFrame, as there is no such parameter for Series. I have thought of three options so far:
1. Include another addition to the substitute, which describes the following: `Instead, ``mapper`` may be used together with ``axis`` to apply the function to the axis values.'`. Notice that this would be only for the DataFrame, and left empty for Series (and Panel). This is similar to `alternative_use` and `axes_alt_types`
2. Include the same description of 1, only in `alternative_use`. However, `alternative_use` is used in the function description as well, hence making a bit of an illogical description. A solution to this would be to remove `alternative_use` from this description, however, this would make the description of Series only include the `Series.name` explanation in it's `index` parameter description.

Note that in the new commit, `mapper` is not included in either of those ways. To be honest, I do not think `axis` and `mapper` are even needed, as the same can be accomplished with `index` or `columns`. Then again, removing these arguments will of course break backwards compatibility, so this is not an option.
@WillAyd Any ideas?
It sounds like there are potentially two issues here:

1. Reduce the duplication of docs between Series.rename and DataFrame.rename (lets ignore panel, it's going away)
2. Differences in behavior between Series.rename and DataFrame.rename

I would isolate number 2 first. For example


```
s.rename(columns={"NONEXISTENT": 'a'}, errors="raise")
```

Seems buggy. I think providing non-None `columns` to Series.rename should raise.

I think once we agree on the correct behavior it'll be easier to document and determine whether or not the  docstrings should be shared.
I see what you mean. I do not think I am the one to decide on the behavior of `Series.rename`!

> Seems buggy. I think providing non-N�one columns to Series.rename should raise.

Even None columns would not make sense though, in the context of Series, since Series does not have columns.

To be honest, I would say to either force the API of Series.rename (i.e. throw on any non-documented argument) or make sure all possible arguments of NDFrame.rename make sense to Series as well, and provide behaviour.
Thanks for the input @TomAugspurger. Mentioned above but we have a similar handling of the reindex method. I *think* we can just mimic that substitution behavior for this PR. 

Agreed we can also change up some things with implementation but I don't think that's a blocker for this and could be subsequent PR
cc @jorisvandenbossche @datapythonista 
good idea, but closing as stale