We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.

This lesson's interactive features are locked, please to keep using them

Conditional Updates

Filtering creates a new DataFrame containing only the rows that match a condition. But sometimes you may want to keep all rows while updating some of them.

For this, we can use .loc[] with a boolean mask and a column name:

needs_service = df["battery_level"] < 20
df.loc[needs_service, "status"] = "needs service"

The first input to .loc[] is a mask that selects rows with battery_level under 20; the second input selects the status column as the one to update. Rows with a low battery level will get a status of "needs service", while other rows are left unchanged.

Assigning through .loc[] modifies the DataFrame directly. If you need to preserve the original data, create a copy before updating rows.

Update Operations

You can also perform an operation on the selected values. For example, to increment the count of connection retries for offline devices:

is_offline = df["status"] == "offline"
df.loc[is_offline, "retry_count"] += 1

Don't try to do this with a chained assignment like df[is_offline]["retry_count"] += 1. The first selection produces a temporary DataFrame, so the update never reaches df. Pandas will also emit a ChainedAssignmentError warning.

Assignment

SnackStack's devices report energy usage in mixed units: some use watt-hours ("Wh"), while others use kilowatt-hours ("kWh"). The analytics team needs every reading in kilowatt-hours. 1 kilowatt-hour is equal to 1000 watt-hours.

Complete the normalize_energy_units function. It accepts a DataFrame with device_id, energy_usage, and energy_unit columns. The energy_usage values are floats, and each energy_unit is either "Wh" or "kWh". The function should return a new DataFrame with all energy readings expressed in kilowatt-hours.