23. Common pandas Mistakes and Fixes
23.1 SettingWithCopy and Chained Assignment
Why. You filter Pune rows, then set delivery_mins = 12, and nothing sticks — or pandas warns. Shraddha loses twenty minutes thinking the dark store data “won’t update”.
What. Chained assignment means two __getitem__ steps in one line, like df[df.city == "Pune"]["mins"] = 12. pandas may give you a copy, so the write vanishes. Prefer .loc on the original frame, or work on an explicit .copy().
How.
Safe patterns
- Prefer
df.loc[mask, "col"] = value. - If you need a subset frame:
pune = df.loc[mask].copy()then editpune. - Do not ignore
SettingWithCopyWarning— treat it as a bug report. - After a write,
print(df.loc[mask, "col"].head())to verify. - For new columns from filters, assign into
dfwith.locornp.where.
Worked example A — Broken vs fixed.
import pandas as pd
df = pd.DataFrame({
"order_id": ["BLK-1", "BLK-2", "BLK-3", "AMN-4"],
"city": ["Pune", "Pune", "Nashik", "Kolhapur"],
"delivery_mins": [18, 22, 11, 10],
"customer": ["Ruhi Bagale", "Amir", "Zoya", "Ravina"],
})
# Fragile — may not write back
df[df["city"] == "Pune"]["delivery_mins"] = 12
print("after chain", df["delivery_mins"].tolist())
# Clear — writes on df
df.loc[df["city"] == "Pune", "delivery_mins"] = 12
print("after loc", df["delivery_mins"].tolist())
Worked example B — Explicit copy for a side analysis.
pune = df.loc[df["city"] == "Pune"].copy()
pune["sla_flag"] = pune["delivery_mins"] <= 15
print(pune[["order_id", "sla_flag"]])
# original df has no sla_flag — intentional
print("sla in df?", "sla_flag" in df.columns)
Worked example C — New column with np.where.
import numpy as np
df = df.copy()
df["late"] = np.where(df["delivery_mins"] > 15, "Late", "OK")
print(df[["city", "delivery_mins", "late"]])
Raja in Nagpur uses the same pattern for cancel flags — one column, no chain.
Ravindra Bagale's Tip
Shortcut: df.loc[rows, cols] = ... lihaycha try kara. Warning ale ki chain sodun loc.