Adding and Dropping Columns
Overview
A new column is an assignment, and drop returns a new table by default.
What You Will Learn in This Lesson
By the end of this lesson, you will be able to:
- Create a derived column from the columns you already have.
- Say what
dropreturns, and what it leaves behind. - Take a copy before modifying a table a caller still owns.
- Rename a column without rebuilding the table.
Why This Matters
The column that answers your question is usually not in the file — it is a rate, a difference, a share. Deriving one is a single assignment, and the only real trap is that half of these operations return a new table while the other half change yours, and the difference is not visible until something downstream is wrong.
Step 1: A derived column
Assigning to a name that does not exist creates it. The right-hand side is ordinary column arithmetic, applied to the whole column at once.
Create by assigning
No method call and no declaration. If the name exists it is replaced; if not, it is added at the end.
import pandas as pd
df = pd.DataFrame({"price": [10.0, 20.0]})
df["with_tax"] = df["price"] * 1.08
print(df)
From two columns
The arithmetic aligns on the index, so the rows always line up with themselves. This is the everyday case: a total, a rate, a difference from a target.
import pandas as pd
df = pd.DataFrame({"price": [2.0, 5.0], "quantity": [3, 2]})
df["total"] = df["price"] * df["quantity"]
print(df)
Renaming
rename takes a mapping and, like drop, hands back a new table unless you tell it otherwise.
import pandas as pd
df = pd.DataFrame({"n": [1, 2]})
print(df.rename(columns={"n": "count"}).columns.tolist())
print(df.columns.tolist()) # unchanged
Mini Practice #1: A rate per head
Try It YourselfAdd a per_person column equal to total divided by people, then a rounded column holding it to one decimal place.
Step 2: Dropping returns a copy
drop hands back a new table and leaves yours alone unless you reassign. This surprises people who expect it to behave like a list method.
The result is the point
Calling drop and ignoring what it returns looks exactly like a no-op, because it is one.
import pandas as pd
df = pd.DataFrame({"a": [1], "b": [2]})
smaller = df.drop(columns=["b"])
print(list(smaller.columns))
print(list(df.columns)) # still both
Assignment is not a copy
Two names for the same table are still one table. A function that assigns a column onto the DataFrame it was handed has changed its caller's data, and nothing says so.
import pandas as pd
def add_flag(table):
table["flag"] = True # edits the caller's table
return table
df = pd.DataFrame({"a": [1]})
add_flag(df)
print(list(df.columns))
Copy first
One extra line makes the function honest: it returns something new and leaves what it was given alone.
import pandas as pd
def add_flag(table):
out = table.copy()
out["flag"] = True
return out
df = pd.DataFrame({"a": [1]})
add_flag(df)
print(list(df.columns)) # untouched
Mini Practice #2: Which one changed
Try It YourselfRun this and note which of the two prints shows the extra column. Then add .copy() and run it again.
Step 3: When to Use It
A derived column
Assign an expression over existing columns to a new name.
df["percent"] = df["score"] / df["total"] * 100
Removing columns you will not use
drop(columns=[...]) returns a smaller table that is easier to read and check.
When Not to Use It
Do not expect drop to change the table in place. It returns a new DataFrame — assign the result, or the column is still there.
End-of-Lesson Exercises
Exercise 1: Add a total, leave the original alone
Write add_total(df) that returns a new table with a total column equal to price times quantity, leaving the table it was given unchanged.
Take a copy first, then assign the new column onto the copy. Assigning straight onto df would change the caller's table, which the hidden case checks.
Exercise 2: Keep only what you need
Write only(df, keep) that returns a new table holding just the columns named in keep, in that order, without changing the table it was given.
df[keep] with a list of names already gives a new table in the order you asked for. Add .copy() so later edits to the result cannot reach back.