pandas
data manipulation
Python
conditional update
data analysis

Update row values where certain condition is met in pandas

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Conditional updates are one of the most common pandas operations. The important part is not just changing the right values, but doing it in a way that is vectorized, readable, and free of SettingWithCopyWarning.

Use loc for Direct Conditional Updates

The standard pattern is to build a boolean mask and assign through loc. This is fast, explicit, and works well for most cases.

python
1import pandas as pd
2
3df = pd.DataFrame(
4    {
5        "product": ["A", "B", "C", "D"],
6        "category": ["Electronics", "Office", "Electronics", "Office"],
7        "sales": [100, 80, 150, 60],
8    }
9)
10
11mask = df["category"] == "Electronics"
12df.loc[mask, "sales"] = df.loc[mask, "sales"] * 1.10
13
14print(df)

mask marks the rows to update, and df.loc[mask, "sales"] selects only the target cells. This is the approach to reach for first.

You can update multiple columns at once too:

python
1vip_mask = df["sales"] >= 100
2df.loc[vip_mask, ["category", "sales"]] = ["Priority", 999]
3
4print(df)

That pattern is useful when a business rule changes several fields together.

Build More Complex Conditions

Real datasets rarely depend on a single equality check. Boolean conditions compose naturally with &, |, and ~. Remember to wrap each comparison in parentheses.

python
1import pandas as pd
2
3orders = pd.DataFrame(
4    {
5        "customer": ["Ana", "Ben", "Cara", "Dan"],
6        "amount": [120, 45, 300, 75],
7        "status": ["new", "new", "new", "paid"],
8    }
9)
10
11mask = (orders["amount"] > 100) & (orders["status"] == "new")
12orders.loc[mask, "status"] = "priority"
13
14print(orders)

This reads almost like prose: for rows where amount is above 100 and status is new, replace the status with priority.

If the updated value depends on a condition, where and mask are also useful:

python
1orders["discount"] = 0
2orders["discount"] = orders["discount"].where(orders["amount"] < 100, 15)
3
4print(orders)

Here, rows below 100 keep the original value, while the others become 15.

When np.where or assign Is Cleaner

For a new column derived from a condition, np.where can be compact and expressive.

python
1import numpy as np
2import pandas as pd
3
4df = pd.DataFrame({"score": [45, 72, 88, 59]})
5
6df["result"] = np.where(df["score"] >= 60, "pass", "fail")
7print(df)

If you prefer chainable transformations, use assign:

python
1df = df.assign(
2    band=np.where(df["score"] >= 80, "high", "standard")
3)
4
5print(df)

This style is handy inside larger cleaning pipelines where you want each transformation to remain visible.

Updating Based on Another DataFrame

Sometimes the new values come from another table. In that case, merge first or align by index, then assign.

python
1import pandas as pd
2
3inventory = pd.DataFrame(
4    {"sku": ["A1", "B2", "C3"], "price": [10, 20, 30]}
5)
6price_updates = pd.DataFrame(
7    {"sku": ["B2", "C3"], "new_price": [22, 35]}
8)
9
10merged = inventory.merge(price_updates, on="sku", how="left")
11mask = merged["new_price"].notna()
12merged.loc[mask, "price"] = merged.loc[mask, "new_price"]
13result = merged.drop(columns=["new_price"])
14
15print(result)

Trying to loop row by row is slower and usually harder to maintain than aligning the data first.

Common Pitfalls

The biggest one is chained indexing, such as df[df["x"] > 0]["y"] = 1. That may modify a temporary object instead of the original DataFrame. Use loc instead.

Another common issue is forgetting parentheses in compound boolean expressions. In pandas, & and | do not behave correctly without explicit grouping around each comparison.

Type mismatches can also cause confusing results. If a numeric column was loaded as strings, comparisons and assignments may behave unexpectedly. Inspect df.dtypes before applying business rules.

Finally, avoid apply(axis=1) for simple conditional updates. It is often slower and less clear than vectorized masks.

Summary

  • 'df.loc[mask, column] = value is the core pattern for conditional updates in pandas.'
  • Boolean masks can combine multiple conditions with &, |, and ~.
  • Use np.where, where, or assign when they make the transformation clearer.
  • Avoid chained indexing because it can update a copy instead of the original DataFrame.
  • Prefer vectorized operations over row-wise apply for performance and clarity.

Course illustration
Course illustration

All Rights Reserved.