Lesson 11
Adding Columns and Rows
Grow a DataFrame: build a new column from a value or an expression, place one at a chosen position, and append rows with loc or concat.
Assigning to a name that does not exist yet creates a column. The value can be a single number, a list of the right length, or an expression over the columns you already have, which is where pandas saves you a loop.
A column from a value
Assign a single value and pandas repeats it down the column. Assign a list and it must have exactly one value per row, or you get a ValueError.
import pandas as pd
learners = pd.DataFrame({
"name": ["Avery", "Jordan", "Casey"],
"score": [88, 74, 91],
})
learners["term"] = "autumn"
learners["group"] = [1, 2, 1]
print(learners)Output:
name score term group
0 Avery 88 autumn 1
1 Jordan 74 autumn 2
2 Casey 91 autumn 1A column from the other columns
An expression over whole columns runs element by element, with no loop in sight. round keeps the result readable, and comparisons give a Boolean column you can filter on later.
import pandas as pd
learners = pd.DataFrame({
"name": ["Avery", "Jordan", "Casey", "Riley", "Morgan", "Quinn"],
"track": ["Python", "NumPy", "Python", "pandas", "NumPy", "pandas"],
"city": ["Northgate", "Eastport", "Northgate", "Westfield", "Eastport", "Westfield"],
"hours": [42, 31, 55, 24, 47, 38],
"score": [88, 74, 91, 65, 82, 79],
})
learners["per_hour"] = (learners["score"] / learners["hours"]).round(2)
learners["passed"] = learners["score"] >= 75
print(learners[["name", "hours", "score", "per_hour", "passed"]])Output:
name hours score per_hour passed
0 Avery 42 88 2.10 True
1 Jordan 31 74 2.39 False
2 Casey 55 91 1.65 True
3 Riley 24 65 2.71 False
4 Morgan 47 82 1.74 True
5 Quinn 38 79 2.08 TruePlace a column where you want it
Assignment always adds at the right. insert takes a position, a name, and the values, so a label column can sit next to the name it describes.
import pandas as pd
learners = pd.DataFrame({
"name": ["Avery", "Jordan", "Casey", "Riley", "Morgan", "Quinn"],
"track": ["Python", "NumPy", "Python", "pandas", "NumPy", "pandas"],
"city": ["Northgate", "Eastport", "Northgate", "Westfield", "Eastport", "Westfield"],
"hours": [42, 31, 55, 24, 47, 38],
"score": [88, 74, 91, 65, 82, 79],
})
learners.insert(1, "level", ["mid", "new", "senior", "new", "mid", "mid"])
print(learners.head(3))
print(learners.columns.tolist())Output:
name level track city hours score
0 Avery mid Python Northgate 42 88
1 Jordan new NumPy Eastport 31 74
2 Casey senior Python Northgate 55 91
['name', 'level', 'track', 'city', 'hours', 'score']assign leaves the original alone
assign returns a new DataFrame with the extra columns, which suits a chain of steps where you do not want to touch the source table.
import pandas as pd
learners = pd.DataFrame({
"name": ["Avery", "Jordan", "Casey", "Riley", "Morgan", "Quinn"],
"track": ["Python", "NumPy", "Python", "pandas", "NumPy", "pandas"],
"city": ["Northgate", "Eastport", "Northgate", "Westfield", "Eastport", "Westfield"],
"hours": [42, 31, 55, 24, 47, 38],
"score": [88, 74, 91, 65, 82, 79],
})
report = learners.assign(
per_hour=(learners["score"] / learners["hours"]).round(2),
busy=learners["hours"] > 40,
)
print(report[["name", "per_hour", "busy"]])
print(learners.columns.tolist())Output:
name per_hour busy
0 Avery 2.10 True
1 Jordan 2.39 False
2 Casey 1.65 True
3 Riley 2.71 False
4 Morgan 1.74 True
5 Quinn 2.08 False
['name', 'track', 'city', 'hours', 'score']Add a row
.loc[new_label] = [...] writes one row, and len(df) is the next free position when the index counts from 0. For several rows, build a small DataFrame and concat it, which is far cheaper than appending one row at a time.
import pandas as pd
learners = pd.DataFrame({
"name": ["Avery", "Jordan"],
"hours": [42, 31],
})
learners.loc[len(learners)] = ["Casey", 55]
print(learners)
extra = pd.DataFrame({"name": ["Riley", "Morgan"], "hours": [24, 47]})
learners = pd.concat([learners, extra], ignore_index=True)
print(learners)Output:
name hours
0 Avery 42
1 Jordan 31
2 Casey 55
name hours
0 Avery 42
1 Jordan 31
2 Casey 55
3 Riley 24
4 Morgan 47ignore_index=True renumbers the rows so the labels stay unique.
Key takeaways
-
Assigning to a new name creates a column at the right-hand end
-
A single value fills the column; a list must match the row count
-
insert places a column at a chosen position and assign returns a new table
-
Use .loc for one row and pd.concat for many
-
Next: Updating Values
-
Previous: Filtering Rows
Loading playground…
Check your understanding
Adding Columns and Rows Quiz
What does assigning to a name that does not exist do?
1 / 10