pandas apply KeyError (missing axis=1)

df.apply(lambda row: row['price']) raising KeyError: 'price' for a column that exists means you forgot axis=1: by default apply passes each column, indexed by row labels, not each row. Add axis=1, or replace the apply with a vectorised column expression. Tested on pandas 2.3.3 and 3.1.0.

1. The cause: apply passes columns unless you say axis=1

import pandas as pd
df = pd.DataFrame({"price": [2.0, 3.0], "qty": [5, 4]})
try:
    df.apply(lambda row: row["price"] * row["qty"])
except KeyError as e:
    print("KeyError:", e)
df.apply(lambda col: print(type(col).__name__, col.name, col.index.tolist()))
print(df.apply(lambda row: row["price"] * row["qty"], axis=1).tolist())

Output, identical on pandas 2.3.3 and 3.1.0:

KeyError: 'price'
Series price [0, 1]
Series qty [0, 1]
[10.0, 12.0]

DataFrame.apply defaults to axis=0: your function receives each column as a Series whose index is the row labels [0, 1]. So row["price"] looks for a row labelled price and raises KeyError: 'price', naming a column that plainly exists. Adding axis=1 passes one row at a time, indexed by column names.

2. Better: skip apply, or use .get for optional columns

import pandas as pd
df = pd.DataFrame({"price": [2.0, 3.0], "qty": [5, 4]})
df["total"] = df["price"] * df["qty"]
print(df["total"].tolist())
rows = pd.DataFrame({"price": [2.0, None]})
print(rows.apply(lambda r: r.get("qty", 1) * r["price"], axis=1).tolist())

Output, identical on pandas 2.3.3 and 3.1.0:

[10.0, 12.0]
[2.0, nan]

For arithmetic between columns, a vectorised expression gives the same result as the axis=1 apply without a Python call per row. If the KeyError is real, because some frames lack the column, a row is a Series, so r.get("qty", 1) returns a default instead of raising. Missing values propagate as nan rather than raising. If the function itself fails on some values, see pandas apply errors='coerce'.

Related: KeyError on a column that exists · KeyError: not in index · pivot_table KeyError.

Frequently asked questions

Why does pandas apply give KeyError for an existing column?

DataFrame.apply defaults to axis=0, so the function gets columns indexed by row labels; row['col'] then looks up a row label. Pass axis=1 to get rows.

How do I avoid KeyError in apply when a column might be missing?

Each row is a Series, so use row.get('col', default) instead of row['col'].

Is apply with axis=1 slow?

It calls your Python function once per row. For arithmetic between columns, df['a'] * df['b'] gives the same result without the per-row call.

Written with AI assistance. Measured on 2026-10-23 in the python:3-alpine Docker image (Python 3.14.7) with pandas 2.3.3 and pandas 3.1.0. Outputs pasted unedited. PlainTables is our extension; Python and pandas are free.