Use df.rename() to rename a pandas column, several columns, or index labels without rebuilding the DataFrame. The method accepts explicit old-to-new mappings for targeted edits and callable functions for systematic cleanup.
By default, rename() returns a new DataFrame and leaves the original unchanged. That behavior makes it suitable for a clear, assignable pandas DataFrame’s rename method.
How to rename a DataFrame column or several columns with df.rename()
Use columns={old: new} when you rename a pandas DataFrame
Pass a dictionary to columns. Each key is the existing column label, and each value is its replacement. The mapping always goes from old name to new name:
renamed = df.rename(columns={“Name”: “name”})
This creates a new DataFrame with Name changed to name. The original df still has its original labels. To rename several columns, include multiple entries:
renamed = df.rename(columns={
“First Name”: “first_name”,
“Order Total”: “order_total”
})
Columns not listed in the dictionary remain unchanged. This is the direct way to rename a DataFrame column when you know the exact labels. Do not reverse the dictionary: {“name”: “Name”} searches for a column already named name and changes it to Name.
Should you return a new DataFrame or change a DataFrame column name in place?
Return a new DataFrame by default and assign it
The default operation returns a renamed copy-like DataFrame object:
df2 = df.rename(columns={“old_name”: “new_name”})
Use assignment when you want to preserve the original DataFrame, keep a clearly named transformed object, or chain the result with other operations. You can also replace the original variable:
df = df.rename(columns={“old_name”: “new_name”})
Use inplace=True when you do not need a returned object
Set inplace=True to update df directly:
df.rename(columns={“old_name”: “new_name”}, inplace=True)
This operation returns None, so do not assign its result back to df. Choose the default returned-DataFrame behavior when you want easier debugging, reversible steps, or a transformation pipeline. Choose in-place behavior when direct mutation is intentional and you do not need the method’s return value.
Choose errors=’raise’ or ‘ignore’ for missing labels
By default, errors=”ignore” leaves a mapping unchanged if its old label is absent. To catch misspelled or unexpected labels, use:
df.rename(columns={“Oder Total”: “order_total”}, errors=”raise”)
A missing source label then raises a KeyError. Use errors=”ignore” when a mapping may apply only to some DataFrames, and errors=”raise” when every requested rename must succeed.
How to transform every column label with a callable
Use a callable to clean labels and display the final columns
Pass a function to columns when every label needs the same transformation. The callable receives one label at a time and must return its replacement. This example strips surrounding whitespace, converts labels to lowercase, and replaces spaces with underscores:
clean = df.rename(
columns=lambda column: column.strip().lower().replace(” “, “_”)
)
For input labels Customer ID, Order Total, and Order Date, display the result with:
print(clean.columns.tolist())
[‘customer_id’, ‘order_total’, ‘order_date’]
A callable is useful for consistent label cleanup, while a dictionary is safer when only selected columns should change. If labels are not all strings, account for their types before calling string methods.
How to rename index labels or a MultiIndex level
Rename ordinary index labels
Use index instead of columns to rename row labels:
df2 = df.rename(index={0: “first”, 1: “second”})
This changes labels, not row positions or the values stored in the DataFrame.
Rename one level of a MultiIndex
For hierarchical columns or rows, supply the level name or number. To rename labels in the second level of a MultiIndex column:
df2 = df.rename(
columns={“Q1”: “first_quarter”},
level=1
)
Use index= for a MultiIndex on rows. The level argument limits the mapping to one hierarchy level, leaving labels in the other levels unchanged.
