Module 08 · Core

Create and update columns

Calculate new fields, tidy column names, and change selected values safely.

Before you start: Know arithmetic, column selection, Boolean masks, and assignment.

Python loads from this site on your first run.

Each run starts with fresh data. Download any exported files before another run. Your written answers and code drafts are saved on this device; export your work to keep a backup.

M08C01 · Explore · predict · practice

Calculate a new column

Assign a Series to a new column name to add a field. Arithmetic across columns works row by row after index alignment. Here the artificial Score_Per_Hour ratio demonstrates division; it is not a validated measure of student ability. Always consider units and the meaning of a calculation.

Read the example

df = students()
df["Score_Per_Hour"] = df["Score"] / df["Study_Hours"]
result = df[["Name", "Score", "Study_Hours", "Score_Per_Hour"]]
print(result.head(3).round(2))
Verified example output · pandas 2.2.3
    Name  Score  Study_Hours  Score_Per_Hour
0  Amira     88            8           11.00
1  Bilal     72            5           14.40
2  Chloe     91            9           10.11

Watch for this. Before dividing by a column, check for zero and missing denominators; they can create undefined results.

Your turn

Start with a fresh df = students(). Create Score_Fraction by dividing Score by 100. Store Name, Score, and Score_Fraction for all students in result, then print its first three rows.

For the code check, keep these result variable names: df, result. Different valid approaches are welcome.

Show a hint

Assign the division result to df["Score_Fraction"].

Show one worked solution
df = students()
df["Score_Fraction"] = df["Score"] / 100
result = df[["Name", "Score", "Score_Fraction"]]
print(result.head(3))

The first fractions are 0.88, 0.72, and 0.91. The original Score remains measured out of 100.

Compare your explanations
  1. Read. df["Score_Per_Hour"] on the left side.
  2. Predict. 11.0, from 88 divided by 8.
  3. Explain. The ratio alone does not measure learning quality or account for other factors. It is only an arithmetic example with fictional data.

One quick check

What happens when you assign to a column name that does not yet exist?

What you should be able to explain. I can create a calculated column and state its units and limits.

M08C02 · Explore · predict · practice

Use assign, rename, and drop

assign() returns a DataFrame with new or replaced columns. rename(columns=...) changes column labels, while drop(columns=...) removes named columns. These methods return new objects by default. Assign the returned result so your intended changes are kept.

Read the example

df = students()
result = (df.assign(Passed=df["Score"] >= 60)
            .rename(columns={"Name": "Student_Name"})
            .drop(columns=["Join_Date"]))
print(result[["Student_Name", "Score", "Passed"]].head(4))
print("Result shape:", result.shape)
Verified example output · pandas 2.2.3
  Student_Name  Score  Passed
0        Amira     88    True
1        Bilal     72    True
2        Chloe     91    True
3         Dana     65    True
Result shape: (12, 9)

Watch for this. Calling df.drop(...) without assigning its returned result does not change df by default.

Your turn

Use assign to create Needs_Support for scores below 70. Rename Attendance to Attendance_Percent and drop Join_Date. Keep the result in result.

For the code check, keep these result variable names: df, result. Different valid approaches are welcome.

Show a hint

Provide a Boolean Series to assign, a mapping to rename, and a list of names to drop.

Show one worked solution
df = students()
result = (df.assign(Needs_Support=df["Score"] < 70)
            .rename(columns={"Attendance": "Attendance_Percent"})
            .drop(columns=["Join_Date"]))
print(result[["Name", "Score", "Needs_Support", "Attendance_Percent"]])

Needs_Support is True for Dana, Hassan, and Khalid. The longer attendance name makes the unit explicit. df remains available in its original form.

Compare your explanations
  1. Read. True for scores at least 60 and False otherwise, using the rule stated in this example.
  2. Predict. No. In result it has been renamed Student_Name. The original df still has Name.
  3. Explain. It starts with nine, adds Passed, then drops Join_Date: 9 + 1 - 1 = 9.

One quick check

Which removes a named column from the returned table?

What you should be able to explain. I can add fields and tidy column structure while keeping the original available.

M08C03 · Explore · predict · practice

Update the original with one loc assignment

Use one .loc[row_condition, column_name] assignment to change selected values in a DataFrame. This explicitly identifies both the rows and the field being changed. Avoid chained assignment such as df[mask]["Score"] = value; it does not reliably update the intended original object and does not do so under pandas 3 Copy-on-Write.

Read the example

df = students()
mask = df["Student_ID"] == "S004"
df.loc[mask, "Score"] = 67
result = df.loc[mask, ["Student_ID", "Name", "Score"]]
print(result)
Verified example output · pandas 2.2.3
  Student_ID  Name  Score
3       S004  Dana     67

Watch for this. Repeatedly running an incremental update on the same table would repeat the bonus; this cell starts with a fresh table each time.

Your turn

Apply a practice bonus of 3 points to students with Attendance at least 95. Cap scores at 100 and show only the updated students.

For the code check, keep these result variable names: df, result. Different valid approaches are welcome.

Show a hint

Use one .loc[mask, "Score"] assignment; calculate from the same selected Score values and clip at 100.

Show one worked solution
df = students()
mask = df["Attendance"] >= 95
df.loc[mask, "Score"] = (df.loc[mask, "Score"] + 3).clip(upper=100)
result = df.loc[mask, ["Student_ID", "Name", "Score", "Attendance"]]
print(result)

Amira, Chloe, Fatima, and Jamal receive the practice bonus. Their scores become 91, 94, 98, and 92. Students outside the mask keep their scores.

Compare your explanations
  1. Read. The Score column for the row whose Student_ID is S004, Dana.
  2. Predict. 67.
  3. Explain. It tells pandas to change the named column in selected rows of df itself, instead of writing into an intermediate selection.

One quick check

Which is the clear way to update selected scores in df?

What you should be able to explain. I can modify selected values using one explicit loc assignment.

M08C04 · Explore · predict · practice

Keep an independent working copy

Assigning original to another name creates an alias: both names refer to the same Python object. copy() creates a separate DataFrame for this ordinary scalar-valued teaching table. Use a fresh copy when you want to experiment without changing the original. Pandas copy rules do not replace the need to understand which object you are editing.

Read the example

original = students()
working = original.copy()
working.loc[0, "Score"] = 0
print("Original first score:", original.loc[0, "Score"])
print("Working first score:", working.loc[0, "Score"])
print("Same object:", working is original)
Verified example output · pandas 2.2.3
Original first score: 88
Working first score: 0
Same object: False

Watch for this. For columns containing nested mutable Python objects, even a deep DataFrame copy does not recursively copy those inner objects; this table uses ordinary scalar values.

Your turn

Copy only the RAK rows into working. Add 1 to their scores in the copy and verify Amira's original score is still 88.

For the code check, keep these result variable names: original, working. Different valid approaches are welcome.

Show a hint

Filter with loc, call .copy(), and update the selected table rather than original.

Show one worked solution
original = students()
working = original.loc[original["Campus"] == "RAK"].copy()
working["Score"] = working["Score"] + 1
print(working[["Name", "Score"]])
print("Amira in original:", original.loc[0, "Score"])

working contains six RAK students with scores increased by 1. Amira has 89 in working and 88 in original.

Compare your explanations
  1. Read. Change values in working while keeping original unchanged.
  2. Predict. 88 for original and 0 for working.
  3. Explain. Both names would refer to the same object; changing working would also be visible through original.

One quick check

What does working = original do?

What you should be able to explain. I can protect source values while testing changes on a separate table.

Further detail: official documentation for this topic.