Adding, Modifying & Dropping Columns

Reviewed & published by Brayan K

Modifying columns means reshaping a DataFrame's structure — creating new columns from existing data, renaming them, and removing the ones you no longer need — so your table holds exactly the information your analysis requires.

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 bracket assignment, derived columns, df.assign(), rename(), drop(), and insert() — the everyday toolkit for transforming tables.

What You'll Learn in This Lesson

1 Adding Columns — Bracket Assignment & Derived Columns

The simplest way to add a column is to assign to a new name: df["new"] = .... If the name doesn't exist yet, pandas creates it; if it does, pandas overwrites it. The right side can be a scalar, a list, or — most powerfully — a calculation over existing columns.

import pandas as pd

df = pd.DataFrame({
    "price": [10.0, 20.0, 30.0],
    "qty":   [2, 1, 3],
})

df["currency"] = "USD"            # same value for every row (scalar)
df["total"]    = df["price"] * df["qty"]   # derived from two columns
import pandas as pd

df = pd.DataFrame({
    "price": [10.0, 20.0, 30.0],
    "qty":   [2, 1, 3],
})

df["currency"] = "USD"                  # scalar -> same on every row
df["total"]    = df["price"] * df["qty"]  # derived column
print(df)

# ✅ Expected output:
#    price  qty currency  total
# 0   10.0    2      USD   20.0
# 1   20.0    1      USD   20.0
# 2   30.0    3      USD   90.0

2 df.assign() and df.rename()

df.assign(new=...) returns a new DataFrame with the column added, leaving the original untouched — ideal for method chaining. df.rename(columns={...}) changes column names using an old-to-new mapping.

# assign returns a NEW frame (original unchanged)
df2 = df.assign(discounted=df["total"] * 0.9)

# rename one or more columns via a mapping dict
df3 = df.rename(columns={"qty": "quantity", "total": "amount"})
import pandas as pd

df = pd.DataFrame({
    "qty":   [2, 1, 3],
    "total": [20.0, 20.0, 90.0],
})

# assign -> brand-new DataFrame with an extra column
df2 = df.assign(after_tax=df["total"] * 1.2)
print(df2)
#    qty  total  after_tax
# 0    2   20.0       24.0
# 1    1   20.0       24.0
# 2    3   90.0      108.0

# rename -> map old names to new names
df3 = df.rename(columns={"qty": "quantity", "total": "amount"})
print(df3.columns.tolist())   # ['quantity', 'amount']

# ✅ Expected output:
#    qty  total  after_tax
# 0    2   20.0       24.0
# 1    1   20.0       24.0
# 2    3   90.0      108.0
# ['quantity', 'amount']

3 Dropping Columns/Rows and df.insert()

df.drop(columns=[...]) removes columns; df.drop(index=[...]) removes rows by their index label. Both return a new DataFrame by default. Use df.insert(loc, name, values) when you need a new column at a specific position instead of the far right.

df.drop(columns=["currency"])        # remove a column -> new frame
df.drop(index=[0, 2])                # remove rows 0 and 2 -> new frame
df.insert(0, "id", [101, 102, 103])  # put "id" first (position 0)
import pandas as pd

df = pd.DataFrame({
    "name":  ["Alice", "Bob", "Carol"],
    "temp":  [1, 2, 3],
    "score": [90, 80, 70],
})

# Drop a column (returns a new frame -> reassign to keep it)
df = df.drop(columns=["temp"])
print(df.columns.tolist())   # ['name', 'score']

# Drop a row by index label
print(df.drop(index=[1]))
#     name  score
# 0  Alice     90
# 2  Carol     70

# Insert a column at position 0 (the front)
df.insert(0, "id", [101, 102, 103])
print(df.columns.tolist())   # ['id', 'name', 'score']

# ✅ Expected output:
# ['name', 'score']
#     name  score
# 0  Alice     90
# 2  Carol     70
# ['id', 'name', 'score']
import pandas as pd

df = pd.DataFrame({
    "item":  ["Pen", "Notebook", "Eraser"],
    "price": [1.50, 3.00, 0.75],
    "qty":   [10, 5, 20],
})

# 🎯 YOUR TURN:
# 1) Add a "revenue" column = price * qty.
# 2) Drop the "qty" column afterwards.
# Replace the ___ blanks.

df["revenue"] = df["price"] ___ df["qty"]   # hint: multiply
df = df.drop(columns=[___])                  # hint: the column name to remove

print(df)
# Expected output:
#        item  price  revenue
# 0       Pen   1.50     15.0
# 1  Notebook   3.00     15.0
# 2    Eraser   0.75     15.0

📋 Quick Reference

TaskSyntaxMutates?
Add / overwrite columndf["x"] = ...Yes
Add (non-destructive)df.assign(x=...)No (returns copy)
Rename columnsdf.rename(columns={...})No (returns copy)
Drop columnsdf.drop(columns=[...])No (returns copy)
Drop rowsdf.drop(index=[...])No (returns copy)
Insert at positiondf.insert(0, "x", vals)Yes

🎯 Mini Challenge: Reshape an Orders Table

Transform an orders DataFrame using every tool from this lesson.

import pandas as pd

orders = pd.DataFrame({
    "unit_price": [5.0, 8.0, 2.0],
    "units":      [3, 1, 10],
    "note":       ["", "rush", ""],
})

orders["subtotal"] = orders["unit_price"] * orders["units"]
orders = orders.assign(tax=orders["subtotal"] * 0.2)
orders = orders.rename(columns={"units": "quantity"})
orders = orders.drop(columns=["note"])
print(orders)

# ✅ Expected output:
#    unit_price  quantity  subtotal  tax
# 0         5.0         3      15.0  3.0
# 1         8.0         1       8.0  1.6
# 2         2.0        10      20.0  4.0

❓ Frequently Asked Questions

Lesson complete — you can reshape any table!

You can add columns by assignment, derive them from existing data, use assign() for safe chaining, rename with a mapping, drop columns and rows, and place columns precisely with insert().

Practice quiz

What does df['new'] = ... do if 'new' does not exist yet?

  • Raises a KeyError
  • Creates the new column
  • Returns a copy
  • Renames a column

Answer: Creates the new column. Bracket assignment creates the column if the name is new, or overwrites it if it exists.

What does df['price'] * df['qty'] do?

  • Multiplies row by row (vectorized), no loop
  • Concatenates strings
  • Needs a for loop
  • Raises an error

Answer: Multiplies row by row (vectorized), no loop. Vectorized math multiplies the two columns element-wise automatically.

What does df.assign(new=...) return?

  • None
  • Just the new column
  • A new DataFrame with the column added
  • The original mutated frame

Answer: A new DataFrame with the column added. assign returns a new DataFrame and leaves the original untouched — great for chaining.

How do you rename columns with df.rename?

  • rename(['a','b'])
  • rename(new='old')
  • rename(map='old:new')
  • rename(columns={'old': 'new'})

Answer: rename(columns={'old': 'new'}). Pass a columns mapping dict of old name to new name.

What does df.drop(columns=['x']) return by default?

  • A new DataFrame without column x
  • None
  • Only column x
  • An error

Answer: A new DataFrame without column x. drop returns a new frame by default; the original is unchanged unless you reassign or use inplace.

Which argument drops rows by their index label?

  • columns=
  • axis='rows'
  • index=
  • subset=

Answer: index=. df.drop(index=[...]) removes rows by index label; columns=[...] removes columns.

When does df.insert() matter over plain bracket assignment?

  • When you need the column at a specific position
  • When mutating is forbidden
  • When the column is numeric
  • Never

Answer: When you need the column at a specific position. insert(loc, name, values) places a column at a chosen index; brackets always append at the far right.

Does df.insert(0, 'id', vals) mutate the DataFrame in place?

  • No, it returns a copy
  • Only if inplace=True
  • Yes, it mutates in place
  • It raises an error

Answer: Yes, it mutates in place. insert modifies the DataFrame in place and errors if the name already exists.

Why might a column from df.assign(...) seem to disappear?

  • assign deletes columns
  • The result wasn't captured (assign doesn't mutate)
  • assign needs inplace
  • Columns expire

Answer: The result wasn't captured (assign doesn't mutate). assign returns a copy; if you don't store it, the original df is unchanged.

If you do df['total'] = df['price'] * df['qty'], where does 'total' appear?

  • At position 0
  • It replaces 'price'
  • It is hidden
  • Appended at the far right

Answer: Appended at the far right. Plain bracket assignment always adds the new column at the right end.

Continue this course

Frequently asked questions

What is the difference between df.assign() and df["new"] = ...?

df["new"] = ... modifies the DataFrame in place and returns nothing. df.assign(new=...) returns a brand-new DataFrame with the column added and leaves the original untouched, which makes it perfect for method chaining.

Does df.drop() change the original DataFrame?

By default no — df.drop(columns=[...]) returns a new DataFrame and the original is unchanged. To modify in place, pass inplace=True, or reassign with df = df.drop(columns=[...]).

When should I use df.insert() instead of df["new"] = ...?

Use df.insert(loc, column, value) when the position of the new column matters. Plain bracket assignment always appends the column to the far right, whereas insert lets you place it at any index.