apply
Series.apply(func) calls a function on each value and returns the results as a new Series; DataFrame.apply(func, axis=1) calls it once per row (axis=0, the default, once per column). Use it for custom logic that has no built-in vectorized equivalent.
Syntax
Series.apply(func) | DataFrame.apply(func, axis=0, result_type=None)| Part | What it is |
|---|---|
func | A function or lambda; for DataFrame.apply it receives a Series (a row or a column) |
axis | 0 applies to each column, 1 to each row |
result_type | "expand" turns a returned list into separate columns |
Examples
import pandas as pd
df = pd.DataFrame({"name": ["Ana", "Ben", "Cara"],
"salary": [50000, 62000, 58000],
"bonus": [5000, 0, 2000]})
df["band"] = df["salary"].apply(lambda x: "high" if x >= 58000 else "low")
dfResult: name salary bonus band 0 Ana 50000 5000 low 1 Ben 62000 0 high 2 Cara 58000 2000 high
df["total"] = df.apply(lambda row: row["salary"] + row["bonus"], axis=1)
df[["name", "total"]]Result: name total 0 Ana 55000 1 Ben 62000 2 Cara 60000
Row-wise with axis=1. For plain arithmetic df["salary"] + df["bonus"] is much faster.
def label(row):
if row["bonus"] == 0:
return "none"
return "paid"
df["bonus_flag"] = df.apply(label, axis=1)
df["bonus_flag"].tolist()Result: ['paid', 'none', 'paid']
Common mistakes
- The function receives a whole column instead of a row: you forgot axis=1 on DataFrame.apply.
- KeyError inside the lambda: the row is a Series, so access fields with row["col"], not row.col when the name has spaces.
- Slow on large frames: apply with a Python function runs row by row; prefer vectorized operations, np.where, np.select or map with a dict.
Practice apply
These drills check your answer on live data, free, no account needed.
- Classify with applyWrite a function that labels an order "small" when qty is under 5, "medium" from 5 to 19, and "large" at 20 or more. Apply it to the `qty` column and return the labels as a Series.
Questions
What is the difference between apply, map and applymap?
Series.map substitutes values using a dict, Series or function; Series.apply calls a function per value; DataFrame.map (applymap before 2.1) calls a function on every cell; DataFrame.apply works per row or column.
How do I apply a function with extra arguments?
Pass them after the function: df["col"].apply(func, args=(10,)) or as keywords: df.apply(func, axis=1, rate=0.2).
How do I conditionally create a column without apply?
np.where(cond, a, b) for two outcomes and np.select([c1, c2], [v1, v2], default) for several; both are vectorized and fast.
Related
- mapHow Series.map works in pandas to recode a column with a dict or lookup Series, apply a function per value, what unmatched values become, and map vs replace.
- transformHow groupby transform works in pandas: broadcast a group sum or mean to each row, share of group total, group-wise normalization, and transform versus agg.
- where, mask and np.whereHow to create a conditional column in pandas: np.where for if-else, np.select for several conditions, Series.where to keep values that pass a test, and mask.
- cut and qcutHow to bin numeric data in pandas: pd.cut for fixed ranges with labels like age bands, pd.qcut for equal-sized quantile groups, right-closed edges and labels.