Renaming & Relabelling Columns and Index
Reviewed & published by Brayan K
Renaming is how you change the labels on a DataFrame — the column headers and index names — without touching the values stored underneath them.
Part of the free Pandas course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Learn to rename selected columns with a dict, relabel the index, replace the whole header list, clean names with .str methods, and tag columns with add_prefix and add_suffix.
What You'll Learn in This Lesson
- Rename selected columns with rename(columns={...})
- Relabel the index with rename(index={...})
- Replace every header via df.columns = [...]
- Clean names with df.columns.str methods
- Tag columns with add_prefix / add_suffix
- Why rename returns a new frame, not in place
1 Surgical Renaming — rename(columns={...})
rename() takes a dictionary that maps old label to new label. Only the labels you list change; everything else is left exactly as it was. That makes it the safe choice when a couple of column names came in wrong and the rest are fine. The same method relabels the row index via index={...}.
import pandas as pd
df = pd.DataFrame({"Name": ["Ann"], "Age in Yrs": [30]})
df = df.rename(columns={"Name": "name", "Age in Yrs": "age"})
# columns are now: name, age
df = df.rename(index={0: "first_row"}) # relabel a row in the indeximport pandas as pd
df = pd.DataFrame({
"Name": ["Ann", "Bob"],
"Age in Yrs": [30, 25],
})
df = df.rename(columns={"Name": "name", "Age in Yrs": "age"})
print(df.columns.tolist())
# The data is untouched, only the labels changed:
print(df.iloc[0].tolist())
# ['Ann', 30]
# ✅ Expected output:
# ['name', 'age']
# ['Ann', np.int64(30)]2 Replacing Every Header — df.columns = [...]
When the whole header row is a mess, it is often quicker to overwrite it entirely. Assigning a list to df.columns replaces all the names at once. The catch: your list must have exactly one name per column, in the right order, or pandas raises a length-mismatch error.
df.columns = ["name", "age", "city"] # must match the column count
# Clean an entire messy header in one expression using .str:
df.columns = (df.columns
.str.strip() # trim whitespace
.str.lower() # lowercase
.str.replace(" ", "_")) # spaces -> underscoresimport pandas as pd
df = pd.DataFrame({
" First Name ": ["Ann"],
"AGE": [30],
"Home City": ["NYC"],
})
# Normalise the whole header in one chain of .str methods
df.columns = (df.columns
.str.strip()
.str.lower()
.str.replace(" ", "_"))
print(df.columns.tolist())
# ✅ Expected output:
# ['first_name', 'age', 'home_city']3 Tagging Columns — add_prefix & add_suffix
Sometimes you want to mark every column with a tag — a quarter, a source name, a units note. add_prefix() bolts a string onto the front of every column name, add_suffix() onto the back. Both return a new DataFrame and leave the values alone. They shine right before a merge, when you need to tell columns from two tables apart.
q1 = pd.DataFrame({"sales": [100], "cost": [60]})
q1.add_prefix("q1_") # columns -> q1_sales, q1_cost
q1.add_suffix("_usd") # columns -> sales_usd, cost_usdimport pandas as pd
q1 = pd.DataFrame({"sales": [100, 120], "cost": [60, 70]})
tagged = q1.add_prefix("q1_")
print(tagged.columns.tolist())
# suffix works the same way, on the other end
print(q1.add_suffix("_usd").columns.tolist())
# ['sales_usd', 'cost_usd']
# ✅ Expected output:
# ['q1_sales', 'q1_cost']
# ['sales_usd', 'cost_usd']import pandas as pd
df = pd.DataFrame({"Full Name": ["Ann"], "YEARS": [30]})
# 🎯 YOUR TURN:
# Rename "Full Name" to "name" and "YEARS" to "age".
# Fill in the keyword argument that rename() uses for column labels.
df = df.rename(___={"Full Name": "name", "YEARS": "age"})
print(df.columns.tolist())
# Expected output:
# ['name', 'age']! Common Errors (And How to Fix Them)
❌ "Length mismatch" assigning df.columns
The replacement list has the wrong number of names:
# df has 3 columns
df.columns = ["name", "age"] # ❌ Length mismatch: 3 vs 2✅ Fix: give exactly one name per column, or use rename:
df.columns = ["name", "age", "city"] # ✅
df = df.rename(columns={"old": "name"}) # ✅ just oneForgot to assign the result back (or a typo in the old name):
df.rename(columns={"Name": "name"}) # ❌ result discarded✅ Fix: reassign the returned frame:
df = df.rename(columns={"Name": "name"}) # ✅🎯 Mini Challenge: Tidy a Spreadsheet Header
An exported sheet has ugly headers. Clean them three ways.
- Lowercase and underscore every column name
- Rename amt to amount
- Prefix everything with q1_
import pandas as pd
df = pd.DataFrame({
"Order ID": [1, 2],
"Amt": [100, 250],
"Region": ["N", "S"],
})
# 1) normalise the header
df.columns = df.columns.str.lower().str.replace(" ", "_")
# 2) fix one specific name
df = df.rename(columns={"amt": "amount"})
# 3) tag every column
df = df.add_prefix("q1_")
print(df.columns.tolist())
# ✅ Expected output:
# ['q1_order_id', 'q1_amount', 'q1_region']❓ Frequently Asked Questions
Lesson complete — your labels are clean!
You can rename selected columns and index labels with rename, replace a whole header via df.columns, scrub names with .str methods, and tag them with add_prefix/add_suffix.
Practice quiz
How do you rename column A to x with rename()?
- df.rename(columns={'A': 'x'})
- df.rename(cols=['x'])
- df.rename('A', 'x')
- df.rename(rows={'A': 'x'})
Answer: df.rename(columns={'A': 'x'}). Pass a dict to the columns= argument: {'A': 'x'}.
What does rename() return by default?
- None, it edits in place
- A new DataFrame, leaving the original unchanged
- Just the new column names
- A boolean
Answer: A new DataFrame, leaving the original unchanged. rename() returns a new frame by default; use inplace=True to mutate.
How do you replace ALL column labels at once via the attribute?
- df.columns.set(['x','y'])
- df.relabel(['x','y'])
- df.columns = ['x', 'y']
- df.headers = ['x','y']
Answer: df.columns = ['x', 'y']. Assigning a list to df.columns replaces every column name.
Which call renames index labels rather than columns?
- df.rename(columns={...})
- df.rename(labels={...})
- df.rename(rows={...})
- df.rename(index={'r0': 'first'})
Answer: df.rename(index={'r0': 'first'}). Use the index= argument to rename row labels.
What does df.add_prefix('p_') do?
- Adds 'p_' to the front of every column name
- Adds a new column 'p_'
- Prefixes every value with p_
- Renames the index
Answer: Adds 'p_' to the front of every column name. add_prefix prepends the string to each column label.
What does df.add_suffix('_x') produce for column A?
- x_A
- A_x
- A
- _xA
Answer: A_x. add_suffix appends the string, turning A into A_x.
How do you lowercase every column name?
- df.lower()
- df.columns.lower()
- df.rename(columns=str.lower)
- df.tolower()
Answer: df.rename(columns=str.lower). Pass the function str.lower to columns= so it maps each name.
What does the inplace=True argument do in rename()?
- Returns a copy
- Renames only the first column
- Reverses the names
- Modifies the original DataFrame and returns None
Answer: Modifies the original DataFrame and returns None. inplace=True mutates the frame directly and returns None.
Which method sets new labels on a chosen axis?
- df.set_axis(['x','y'], axis=1)
- df.set_labels(['x','y'])
- df.axis(['x','y'])
- df.relabel_axis(['x','y'])
Answer: df.set_axis(['x','y'], axis=1). set_axis assigns new labels along axis=0 (rows) or axis=1 (columns).
If a key in the rename dict matches no column, what happens?
- It raises a KeyError
- That entry is ignored and other renames still apply
- All columns are dropped
- The frame becomes empty
Answer: That entry is ignored and other renames still apply. By default rename ignores keys that don't match; only matching labels change.
Continue this course
- Previous: Dropping & Deduplicating Rows
- Next: Counting & Uniques — Summarise categories fast with value_counts, unique, and nunique
- Quick reference: Pandas cheat sheet › Cleaning & Missing Data
Frequently asked questions
What is the difference between rename() and assigning df.columns?
rename(columns={...}) changes only the labels you name and leaves the rest alone, so it is safe when you want to fix one or two columns. Assigning df.columns = [...] replaces the ENTIRE list at once, so the new list must have exactly the right length and order. Use rename for surgical edits and df.columns for a full relabel.
Does rename change the DataFrame in place?
No. By default rename() returns a new DataFrame and leaves the original unchanged. Assign the result back with df = df.rename(columns={...}), or pass inplace=True. Reassignment is the more common and readable style.
How do I clean every column name at once, like lowercasing them?
Use the .str methods on df.columns, which is itself an Index of strings. df.columns = df.columns.str.lower().str.replace(' ', '_') lowercases and replaces spaces in one expression. This is the standard way to normalise a whole header row imported from a messy spreadsheet.
What do add_prefix and add_suffix do?
They bolt a string onto the front or back of every column name. df.add_prefix('q1_') turns 'sales' into 'q1_sales', which is handy for tagging columns before a merge so you can tell which source they came from. They return a new DataFrame and never touch the data itself.