Calculated columns
df['total'] = df['price'] * df['quantity']
df['margin'] = (df['revenue'] - df['cost']) / df['revenue']
df['name'] = df['first'] + ' ' + df['last']
The operation applies to every row at once — no loop required.
Conditional values
import numpy as np
# two outcomes
df['big'] = np.where(df['revenue'] > 1000, 'yes', 'no')
# several outcomes
conditions = [df['revenue'] > 1000, df['revenue'] > 500]
choices = ['gold', 'silver']
df['tier'] = np.select(conditions, choices, default='bronze')
np.select evaluates conditions in order and takes the first match — the same logic as a SQL CASE.
apply, and when to avoid it
df['band'] = df['revenue'].apply(lambda x: 'high' if x > 1000 else 'low')
apply runs your function per row, so it is much slower than a vectorised operation. Reach for np.where or np.select first; keep apply for logic that genuinely cannot be vectorised.
SettingWithCopyWarning
The warning everyone meets
subset = df[df['region'] == 'East']
subset['flag'] = 1 # SettingWithCopyWarningpandas cannot tell whether
subset is a view or a copy, so it warns that your assignment may not affect what you think.The fix is to be explicit:
subset = df[df['region'] == 'East'].copy()
subset['flag'] = 1
# or assign straight into the original
df.loc[df['region'] == 'East', 'flag'] = 1