What is the difference between map, replace and apply in pandas?
Short answer
map substitutes values from a dictionary and turns anything unmapped into NaN, replace substitutes only the values you list and leaves the rest alone, and apply runs a function on every value.
The short version
map translates values through a dictionary and sets anything not in it to NaN. replace swaps only the values you list and leaves everything else untouched. apply runs an arbitrary function on each value. The difference between map and replace on unlisted values is the one that catches people out.
The critical difference
import pandas as pd
s = pd.Series(["a", "b", "c"])
s.map({"a": 1, "b": 2}) # [1.0, 2.0, NaN] <- 'c' became NaN
s.replace({"a": 1}) # [1, 'b', 'c'] <- 'b' and 'c' untouched
map rebuilt the column entirely from the dictionary, so the unmapped c has no value and becomes NaN. replace only substituted a and left the rest exactly as they were.
When to use each
Use map when the dictionary is meant to be complete, and you want anything missing from it to show up as NaN. That NaN is a feature: it tells you your lookup table did not cover a value, which is often a genuine data problem you want to know about.
Use replace when you are patching a few specific values in an otherwise fine column, for example fixing known bad spellings.
df["city"] = df["city"].replace({"Leedz": "Leeds", "Barth": "Bath"})
Keeping unmapped values with map
If you want map's dictionary semantics but to keep unmapped values, fill the gaps afterwards from the original.
mapped = s.map(lookup).fillna(s)
This maps what it can and leaves the rest as they were, combining both behaviours.
Where apply fits
apply runs a function per value, so it handles logic a dictionary cannot express.
s.apply(lambda x: x.upper())
But for this particular example, s.str.upper() is faster and clearer. Reach for apply only when there is no vectorised method and no dictionary that will do the job, because it runs Python once per element.
The performance ordering
For a straight dictionary lookup, map is the fastest of the three, because it is implemented as a lookup rather than a Python call per element. replace is slower, especially with many replacements. apply is slowest, since it calls into Python for every value. So when a dictionary can express what you want, prefer map over apply.
A note on map with a function
map also accepts a function, in which case it behaves much like apply on a Series. The dictionary form is what makes it distinctive, so use map for lookups and apply for genuine per-value logic, keeping the intent clear to whoever reads the code next.
Enjoying these?
Go from piecing together answers to real fluency.
Our courses take you from looking things up to doing the work with confidence, step by step on real data.
Browse the courses