Renaming columns is a common data-cleaning task. Pandas offers several flexible ways to rename columns depending on whether you want to rename a single column, many columns, use a function to transform all names, or do an in-place rename.
Using DataFrame.rename() (recommended)
rename() accepts a columns mapping (old_name → new_name) or a function. By default it returns a new DataFrame. Use inplace=True to modify the same object (note: inplace is discouraged in some workflows — prefer assignment).
import pandas as pd
df = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie'],
'age': [25, 30, 35],
'gender': ['F', 'M', 'M']
})
# Rename single column
df1 = df.rename(columns={'name': 'Full Name'})
print(df1)
# Rename multiple columns and return new DataFrame
df2 = df.rename(columns={'age': 'Age', 'gender': 'Gender'})
print(df2)
# Rename in-place (modifies df)
df.rename(columns={'name': 'Full Name', 'age': 'Age'}, inplace=True)
print(df)
Output:
Full Name age gender 0 Alice 25 F 1 Bob 30 M 2 Charlie 35 M name Age Gender 0 Alice 25 F 1 Bob 30 M 2 Charlie 35 M Full Name Age gender 0 Alice 25 F 1 Bob 30 M 2 Charlie 35 M
Notes – rename() is explicit and readable.
inplace=True returns None; prefer assignment (df = df.rename(…)) for clarity and fewer surprises.
Assigning a new list to df.columns (replace all names)
Directly set df.columns to a new list — quick but you must provide names for all columns.
import pandas as pd
df = pd.DataFrame({
'First Name': ['John', 'Jane', 'Bob'],
'Last Name': ['Doe', 'Doe', 'Smith'],
'Age': [25, 30, 35]
})
# Replace all column names
df.columns = ['Name', 'Surname', 'Years']
print(df)
Output:
Name Surname Years 0 John Doe 25 1 Jane Doe 30 2 Bob Smith 35
When to use – When you want to rename every column in order, e.g., standardizing from external sources.
Using a function to transform column names
Use a function to apply systematic changes (lowercasing, replacing spaces, prefixing).
import pandas as pd
df = pd.DataFrame({
'First Name': ['John', 'Jane'],
'Last Name': ['Doe', 'Doe'],
'Total Salary': [50000, 60000]
})
# Use a function to lower-case and replace spaces with underscores
df_clean = df.rename(columns=lambda s: s.strip().lower().replace(' ', '_'))
print(df_clean)
Output:
first_name last_name total_salary 0 John Doe 50000 1 Jane Doe 60000
Alternative: df.columns = df.columns.str.lower().str.replace(‘ ‘, ‘_’) — see next section.
String operations on df.columns
Pandas String methods on Index are fast and concise for many renames.
import pandas as pd
df = pd.DataFrame({
'First Name': ['Alice', 'Bob'],
'Age (Years)': [25, 30],
'Salary($)': [50000, 60000]
})
# use .str methods to sanitize column names
df.columns = df.columns.str.strip() \
.str.lower() \
.str.replace(r'[\s\(\)\$]+', '_', regex=True) \
.str.strip('_')
print(df.columns)
Output:
Index(['first_name', 'age_years', 'salary'], dtype='object')
You need a consistent programmatic rename across many columns (remove punctuation, lowercase, replace spaces).
Using set_axis() (alternate, can keep inplace-like behavior)
set_axis() can replace axis labels and optionally return a new DataFrame.
import pandas as pd
df = pd.DataFrame({'a': [1], 'b': [2]})
# Replace columns with new labels (returns new object by default)
df2 = df.set_axis(['col_a', 'col_b'], axis=1, inplace=False)
print(df2)
Output:
col_a col_b 0 1 2
Rename using regex or columns.str.replace()
import pandas as pd
df = pd.DataFrame({
'temp(C)': [22, 23],
'humidity(%)': [45, 50]
})
# Remove parentheses and percent sign
df.columns = df.columns.str.replace(r'[()%]', '', regex=True)
print(df.columns)
Output:
Index(['tempC', 'humidity'], dtype='object')
Handling MultiIndex columns (level-aware renames)
If columns are a MultiIndex (e.g., from pivot tables), target a level or use map.
import pandas as pd
import numpy as np
cols = pd.MultiIndex.from_tuples([('A','one'), ('A','two'), ('B','one')])
df = pd.DataFrame(np.arange(9).reshape(3,3), columns=cols)
# Rename top-level 'A' -> 'Alpha' using map on level 0
df.columns = df.columns.set_levels(
[df.columns.levels[0].str.replace('A', 'Alpha'), df.columns.levels[1]],
level=[0,1]
)
print(df.columns)
Output:
MultiIndex([('Alpha', 'one'), ('Alpha', 'two'), ( 'B', 'one')], )
Note: MultiIndex renaming can be subtle — often easier to flatten, rename, then rebuild MultiIndex if needed.
Rename a single column (without modifying original)
import pandas as pd
df = pd.DataFrame({'Name': ['A', 'B'], 'Age':[20,30]})
df2 = df.rename(columns={'Name': 'FirstName'})
print(df2)
Output:
FirstName Age 0 A 20 1 B 30
Rename using columns assignment (rename all)
[sourcecode language="Python"]
import pandas as pd
df = pd.DataFrame({'col1':[1], 'col2':[2]})
df.columns = ['one', 'two']
print(df)
[/sourcecode]
Output:
one two 0 1 2
Renaming column labels is cheap (operates on the Index object, not array data). String operations on Index are vectorized and scale well for many columns. The main cost is creating a new Index object when you reassign df.columns or use rename() without inplace.
Frequently Asked Questions
What’s the safest way to rename columns without risking data loss?
df = df.rename(columns=...) (assignment). Avoid inplace=True in complex pipelines — assignment is explicit and easier to debug. How do I rename all columns to snake_case?
df.columns = df.columns.str.strip().str.lower().str.replace(r'\s+', '_', regex=True)
Can I rename columns using regex (e.g., remove special characters)?
df.columns.str.replace(pattern, repl, regex=True) to apply regex replacements to every column name. How do I rename a column in a MultiIndex DataFrame?
set_levels, rebuild the MultiIndex, or flatten the columns, rename, and re-multiindex as needed. Will renaming columns change the column order?
df = df[['colA','colB',...]]. Are column renames case sensitive?
rename(), ensure exact matches or use case-normalization first. Does renaming columns affect data types or values?
How to avoid duplicate column names after renaming?
duplicates = df.columns[df.columns.duplicated()]. If duplicates exist, adjust your mapping or append suffixes to ensure uniqueness.