ENH: add kwargs `rename` to `Styler.format_index` for overwriting index labels
State: closed

In methods such as `DataFrame.to_latex` and `DataFrame.to_html` the `header` keyword arg was implemented to provide aliases for column headers, instead of using the underlying DataFrame labels.

Currently `Styler.format_index` allows adding a generic formatter to change the display of index labels but this is not an easy way to simply provide a list of string aliases to use instead. PR adds this function, which will simplify the transition of the above methods to Styler implementation.


Labels:
name: Styler
description: conditional formatting using DataFrame.style

Comments:
ok so is the plan to deprecate `header`? why are you adding this rather than we just use the given labels?
> ok so is the plan to deprecate `header`? why are you adding this rather than we just use the given labels?

3 small arguments for use case:

First, progressing `Styler` as a visualisation tool allowing full customisation of the display, independent of the data and label values. This is already possible where you can now apply a formatting function (1 variable input -> str) to indexes, which is very useful, for example, when formatting dates. But a generic function cannot just overwrite the (visible) labels with user specified values, but this `aliases` arg will allow that.

Second, the existing IO methods have this `headers` arg, which allows overwriting column labels with aliases. Personally I think its not sensible to try and squish all the `Styler` functionality (via chaining) into a single `DataFrame.to_html` and `to_latex` call, but the path of least resistance (community approvals wise) seems to be to not take away functionality from existing kwargs. I.e we would likely keep `headers=xx` and use the styler implementation just refactor as a call to `format_index(aliases=xx)`.

Finally, in a more specialised scenario you might want a formatter that uses a loop index, or combines all level values simulatneously to determine an alias, which you then pass directly here. Note that the indexing of the data can still be maintained underneath via the MultiIndex.

```
multiindex = MultiIndex.from_product([["Mac", "Windows"],  ["2GB", "4GB"]])
def relabel(os, ram, loop):
    return f"{loop}_{os}_{ram}"
aliases = [relabel(idx[0], idx[1], i) for i, idx in enumerate(multiindex)]
styler.hide(level=0).format_index(aliases=aliases)

      level 1           data
0_Mac_2GB                  x
1_Mac_4GB                  x
2_Windows_2GB              x
3_Windows_4GB              x
```


 
 
![Screen Shot 2022-01-20 at 19 01 25](https://user-images.githubusercontent.com/24256554/150395810-90ecfcbe-7c7b-4578-8eea-abd2beee3942.png)
![Screen Shot 2022-01-20 at 19 01 40](https://user-images.githubusercontent.com/24256554/150395830-f0447827-8299-4806-bf75-1f189983c6ee.png)
![Screen Shot 2022-01-20 at 19 01 55](https://user-images.githubusercontent.com/24256554/150395834-121fc31b-77d9-465d-b86b-b5a4de304a7c.png)
![Screen Shot 2022-01-20 at 19 02 02](https://user-images.githubusercontent.com/24256554/150395835-77bf0449-0f1a-4f33-b9ed-1114648ae005.png)
![Screen Shot 2022-01-20 at 19 02 16](https://user-images.githubusercontent.com/24256554/150395840-506da3d7-a246-4a4d-a67a-f6b6f8d15207.png)


> not objecting to the need to do this, i get it. but we don't use `alias` _anywhere_; why isn't this _just_ `.rename()`?

`rename` loosely suggests the data is modified, when it is really just displayed. Therefore, included within the `format_index` method.

Didn't really feel this warranted its own method when all other index formatting is done within `format_index`.
(and its not possible to  combine the two so there was that also)

But im not tied to anything; you tell me which you prefer and ill make changes... 
@jreback what about a different kwarg other that `alias`, how about `names` or `labels`?
@jreback feels like this one has stalled and getting push back anyway. If poss please take one last look since it factors into the PRs where I convert the `DataFrame.to_latex` and `DataFrame.to_html` to use the Styler implementation. And if this one is closed then I have to come up with another way of refactoring them. thx
@attack68 circling back around on this.
In order to be able to completely re-write `DataFrame.to_latex` with the `Styler` implementation, this is the last piece of functionality needed on the Styler side. Then issues being faced by users, such as [stackoverflow q](https://stackoverflow.com/questions/72780890/handle-futurewarning-by-converting-pandas-dataframe-table-to-latex-with-function/72793009#72793009), can be automatically addressed.
@attack68 i am sympathetic here as i know you want to make this fully compatible with the existing formaters. The issues i have here are:
- adding yet another keyword to the api, this bloating the api even more.
- we are merging the concerns here. formatting output data and replacing the data, which we *already* have a good way of doing via `.rename_axis` / `.set_axis`. This leads to more than one way to do something. 

I agree that this could be viewed as on the line, but its much nicer to keep this api nice and tight and use the existing fluent api to solve this problem.

I see that we *already* have styler methods to do some index manipulation e.g. https://pandas.pydata.org/pandas-docs/dev/reference/api/pandas.io.formats.style.Styler.format_index.html?highlight=styler (`.apply_index`, `format_index`). I guess ok to add a `.rename_index` as a method here might be ok. (this preserves the fluent api and doesn't add yet another keyword).
@jreback, OK, yes I see your point, `rename_index` could also serve an additional purpose, which I will explain in the docs write up. Will look to do that instead.