df.rename: How to rename a pandas column in a DataFrame

Python example using df.rename to update DataFrame column labels

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.