Pandasdrill

Cleaning Updated November 2026

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)
PartWhat it is
funcA function or lambda; for DataFrame.apply it receives a Series (a row or a column)
axis0 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")
df

Result: 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.

Previous: pivotNext: map