Use set_levels:

In [22]:
df.columns.set_levels(['b1','c1','f1'],level=1,inplace=True)
df

Out[22]:
     a         d
    b1   c1   f1
0    1    2    3
1   10   20   30
2  100  200  300

rename sets the name for the index, it doesn't rename the column names:

In [26]:
df.columns = df.columns.rename("b1", level=1)
df

Out[26]:
      a         d
b1    b    c    f
0     1    2    3
1    10   20   30
2   100  200  300

This is why you get the error

Answer from EdChum on Stack Overflow
🌐
Pandas
pandas.pydata.org › pandas-docs › version › 0.22 › generated › pandas.MultiIndex.rename.html
pandas.MultiIndex.rename — pandas 0.22.0 documentation
>>> Index([1, 2, 3, 4]).set_names('foo') Int64Index([1, 2, 3, 4], dtype='int64') >>> Index([1, 2, 3, 4]).set_names(['foo']) Int64Index([1, 2, 3, 4], dtype='int64') >>> idx = MultiIndex.from_tuples([(1, u'one'), (1, u'two'), (2, u'one'), (2, u'two')], names=['foo', 'bar']) >>> idx.set_names(['baz', 'quz']) MultiIndex(levels=[[1, 2], [u'one', u'two']], labels=[[0, 0, 1, 1], [0, 1, 0, 1]], names=[u'baz', u'quz']) >>> idx.set_names('baz', level=0) MultiIndex(levels=[[1, 2], [u'one', u'two']], labels=[[0, 0, 1, 1], [0, 1, 0, 1]], names=[u'baz', u'bar'])
Discussions

ENH: Rename multi-level columns or indices using their tupelized names
It's currently quite difficult to rename a single column (or row) in a multi-indexed DataFrame. The problem is illustrated also in this SO article. The current approach requires at least 3 step... More on github.com
🌐 github.com
3
November 25, 2020
python - Pandas - Create Multiindex columns during rename - Stack Overflow
I'm trying to find a simple way to rename a flat column index to a hierarchical multindex column set. I've come across one way, but it seems a bit kludgy - is there a better way to do this in Panda... More on stackoverflow.com
🌐 stackoverflow.com
python - pandas multiindex columns rename - Stack Overflow
hi I would like to rename the columns of my df. it has a multiindex columns and I would like to change the second level of it ie I have : ('GDP US Chained 2012 Dollars SAAR', 'GDP CHWG Index') ('G... More on stackoverflow.com
🌐 stackoverflow.com
python - Rename unnamed multiindex columns in Pandas DataFrame - Stack Overflow
1 Pandas dataframes with multi-level columns:rename a specific level of column so that it's same as another level More on stackoverflow.com
🌐 stackoverflow.com
🌐
DEV Community
dev.to › vikramaruchamy › how-to-rename-multi-index-columns-in-pandas-dataframe-170
How to Rename Multi index columns in Pandas Dataframe - DEV Community
April 13, 2022 - In this short tutorial, you've learnt how to rename the columns of the multi-index pandas data-frame using the set_levels() method.
🌐
Saturn Cloud
saturncloud.io › blog › how-to-rename-multiindex-columns-in-pandas-a-guide-for-data-scientists
How to Rename MultiIndex Columns in Pandas A Guide for Data Scientists | Saturn Cloud Blog
June 19, 2023 - As a data scientist, you know that working with large datasets can be challenging. One of the common scenarios in data analysis is when you have multiple levels of indexing in your DataFrame. In such cases, you may need to rename MultiIndex columns in Pandas to make your data more readable ...
🌐
GitHub
github.com › pandas-dev › pandas › issues › 38069
ENH: Rename multi-level columns or indices using their tupelized names · Issue #38069 · pandas-dev/pandas
November 25, 2020 - df = pd.DataFrame([[1,2,3],[3,4,5],[5,6,7], [7,8,9]]) df.columns = pd.MultiIndex.from_tuples([('i','a'),('i','b'),('ii','a')]) # Rename using tuples: df.rename(columns={('i','b'):('ii','b')}) # Rename using current column name (equivalent to 1a) col = df[('i','b')] df.rename(columns={col.name: ('ii','b')})
Author   pandas-dev
🌐
TutorialsPoint
tutorialspoint.com › python_pandas › python_pandas_renaming_multiindex_labels.htm
Python Pandas - Renaming MultiIndex Labels
To rename the labels of the index or columns in a MultiIndexed object, you can use the pandas DataFame.rename() method.
Find elsewhere
🌐
DataScientYst
datascientyst.com › pandas-rename-column-names
How to rename column in Pandas
January 10, 2023 - (1) rename single column df.rename(columns = {'$b':'B'}, inplace = True) (2) rename multiple columns column_map = {'A': 'First', 'B': 'Second'} df = df.rename(columns=column_map) (3) rename multi-index columns cols = pd.MultiIndex.
🌐
DevPress
devpress.csdn.net › bigdata › 62f253767e6682346618506d.html
How to Rename Multi index columns in Pandas Dataframe_python_weixin_0010034-大数据
In this short tutorial, you've learnt how to rename the columns of the multi-index pandas data-frame using the set_levels() method.
🌐
datagy
datagy.io › home › pandas tutorials › pandas dataframes › pandas rename index: how to rename a pandas dataframe index
Pandas Rename Index: How to Rename a Pandas Dataframe Index • datagy
December 15, 2022 - Learn how to rename a Pandas index, including a single index or multi-index, as well as how to drop an index name altogether.
🌐
Pandas
pandas.pydata.org › docs › reference › api › pandas.DataFrame.rename.html
pandas.DataFrame.rename — pandas 3.0.3 documentation
In case of a MultiIndex, only rename labels in the specified level. errors{‘ignore’, ‘raise’}, default ‘ignore’ · If ‘raise’, raise a KeyError when a dict-like mapper, index, or columns contains labels that are not present in the Index being transformed.
🌐
Solix Technologies
solix.com › products › answers › renaming-multiindex-columns-in-pandas-a-data-science-guide
Renaming MultiIndex Columns In Pandas - A Data Science Guide | Solix Technologies, Inc.
June 29, 2025 - One of the simplest ways to rename your MultiIndex columns is by using the setnames method. This method allows you to explicitly name the levels of your MultiIndex. Heres a practical example · import pandas as pd Create a sample DataFrame with MultiIndexarrays = A, A, B, B, one, two, one, ...
🌐
Stack Overflow
stackoverflow.com › questions › 74517802 › pandas-multiindex-columns-rename
python - pandas multiindex columns rename - Stack Overflow
df.columns = pd.MultiIndex.from_tuples([ (col0, col1.lower().replace('index', ''), *more_cols) for col0, col1, *more_cols in df.columns], names=df.columns.names)
🌐
Pandas
pandas.pydata.org › docs › user_guide › advanced.html
MultiIndex / advanced indexing — pandas 3.0.3 documentation
The rename() method is used to rename the labels of a MultiIndex, and is typically used to rename the columns of a DataFrame.
🌐
PYnative
pynative.com › home › python › pandas › rename columns in pandas dataframe
Rename columns in Pandas DataFrame
March 9, 2023 - This is a new approach.( This approach makes this method match the rest of the pandas API) . Use the axis parameter of a df.rename() to rename columns and row index. The axis can be a row or column.
🌐
Apache
spark.apache.org › docs › latest › api › python › reference › pyspark.pandas › api › pyspark.pandas.MultiIndex.rename.html
pyspark.pandas.MultiIndex.rename — PySpark 4.1.1 documentation
>>> df = ps.DataFrame({'a': ['A', 'C'], 'b': ['A', 'B']}, columns=['a', 'b']) >>> df.index.rename("c") Index([0, 1], dtype='int64', name='c') >>> df.set_index("a", inplace=True) >>> df.index.rename("d") Index(['A', 'C'], dtype='object', name='d') You can also change the index name in place. >>> df.index.rename("e", inplace=True) >>> df.index Index(['A', 'C'], dtype='object', name='e') ... >>> psidx = ps.MultiIndex.from_tuples([('a', 'x'), ('b', 'y')]) >>> psidx.names = ['hello', 'pandas-on-Spark'] >>> psidx MultiIndex([('a', 'x'), ('b', 'y')], names=['hello', 'pandas-on-Spark'])
🌐
Pandas
pandas.pydata.org › pandas-docs › version › 0.18 › generated › pandas.MultiIndex.rename.html
pandas.MultiIndex.rename — pandas 0.18.1 documentation
>>> Index([1, 2, 3, 4]).set_names('foo') Int64Index([1, 2, 3, 4], dtype='int64') >>> Index([1, 2, 3, 4]).set_names(['foo']) Int64Index([1, 2, 3, 4], dtype='int64') >>> idx = MultiIndex.from_tuples([(1, u'one'), (1, u'two'), (2, u'one'), (2, u'two')], names=['foo', 'bar']) >>> idx.set_names(['baz', 'quz']) MultiIndex(levels=[[1, 2], [u'one', u'two']], labels=[[0, 0, 1, 1], [0, 1, 0, 1]], names=[u'baz', u'quz']) >>> idx.set_names('baz', level=0) MultiIndex(levels=[[1, 2], [u'one', u'two']], labels=[[0, 0, 1, 1], [0, 1, 0, 1]], names=[u'baz', u'bar'])