How can I rename MultiIndex columns in pandas?
For example here is what I would like to be able to do:
import pandas as pd
df = pd.DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 9]],
columns=pd.MultiIndex.from_tuples([('a', 1), ('a', 2), ('b', 1)]))
df.rename(columns={('a', 1): 'd', ('a', 2): 'e', ('b', 1): 'f'}, errors='raise')
However, this has no effect, returning a DataFrame with the same column names as the original:
a b
1 2 1
0 1 2 3
1 4 5 6
2 7 8 9
I would like to get:
d e f
0 1 2 3
1 4 5 6
2 7 8 9
(I'm using errors='raise'
to ensure I'm referencing the column names correctly.)
This works when you don't have a MultiIndex:
df = pd.DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 9]],
columns=['a1', 'a2', 'b1'])
df.rename(columns={'a1': 'd', 'a2': 'e', 'b1': 'f'}, errors='raise')
Returns:
d e f
0 1 2 3
1 4 5 6
2 7 8 9
I've messed around with variations on this, for example using the level argument and having the new names have the same number of levels but with no luck.
There are other related questions but they tend to focus on solving some larger problems. I can think of ways to get the result I need to solve my larger problem but I'm purposely not asking that here. This approach with rename
seems the most natural and I would like to understand why it doesn't work or what I'm doing wrong. If there is an alternative to rename
that I should be using that is relevant to my question, or pieces of information on rename
proving it doesn't do what I think it should, they would be much appreciated.
The most similar question is here but the answers don't address my question: specifying the values of a single level is inadequate in my example as a single level cannot specify each column uniquely and set_levels
can't address individual columns.