This page is the worked-example companion to Handling Missing Values . The parent note gave you the formulas . Here we grind through every kind of situation a missing-value problem can be — different missingness mechanisms, tiny toy tables, degenerate inputs (all-missing columns, single neighbour), time-series gaps, and an exam-style trap.
Before we compute anything, one promise: no symbol appears before it is earned . If you have not yet read the parent, that is fine — every term is rebuilt below in plain words with a picture.
Definition The words we will use
A row = one thing you measured (one patient, one day). A column / feature = one property (Age, Income).
NaN = "Not a Number" = the cell where a value should be but is empty. Think of it as a hole in the table.
Impute = "guess and fill the hole with a plausible number". The whole game is: what number does the hole probably hold?
Mean x ˉ = add all the numbers, divide by how many there are — the balance point. x ˉ = n 1 ∑ i = 1 n x i , where n is the count and x i is the i -th value.
Median = line the numbers up smallest-to-largest and take the middle one — the value with half below, half above.
Variance σ 2 = n 1 ∑ ( x i − x ˉ ) 2 = the average squared distance from the balance point — a number for "how spread out is the data".
Intuition Why we care about which mechanism
The parent named three mechanisms (why a hole exists):
MCAR — the hole is random, unrelated to anything.
MAR — the hole depends on things you can see (e.g. age).
MNAR — the hole depends on the value that is missing (high earners hide income).
The mechanism decides whether your guess is honest or lies to the model. So every example below is tagged with its mechanism.
Every missing-value problem falls into one of these cells. Our examples below cover all of them — each example is labelled with the cell it hits.
Cell
Data shape
Mechanism
Method that fits
Trap to expose
C1
Numeric, symmetric
MCAR
Mean
variance shrinks
C2
Numeric, skewed / outlier
MCAR
Median
mean gets pulled
C3
Two rows survive
MAR
Listwise deletion
bias by deletion
C4
Feature correlated with another
MAR
KNN / conditional
mean breaks correlation
C5
Time series, short gap
MCAR-ish
Forward fill
flat during a trend
C6
Categorical
MCAR
Mode
mean is meaningless
C7
Degenerate: whole column NaN
—
drop column
no value to borrow
C8
Degenerate: only 1 neighbour
MAR
KNN with K=1
collapses to copy
C9
Real-world word problem
MAR
choose + justify
reasoning, not formula
C10
Exam twist: leakage
MAR
fit on train only
leakage
Ten cells. Ten examples. Let's go.
Worked example Fill the hole with the balance point
Data: [10, 15, NaN, 20, 25]. The sensor dropped one reading at random (MCAR).
Forecast: guess the fill value and whether the spread goes up, down, or stays after filling.
Step 1 — Compute the mean of the observed numbers.
x ˉ = 4 10 + 15 + 20 + 25 = 4 70 = 17.5
Why this step? MCAR means the hole is a typical value, so the balance point of what we did see is our best single guess.
Step 2 — Drop 17.5 into the hole. → [10, 15, 17.5, 20, 25].
Why this step? We assume the missing value came from the same distribution as the others.
Step 3 — Measure spread before and after.
Observed variance (over the 4 seen values): σ 2 = 31.25 .
After filling, variance over 5 values: σ 2 = 25.0 .
Why this step? To expose the trap: a value placed exactly at the mean adds zero distance-from-mean, so it dilutes the average distance. See the figure — the amber bar sits on the balance line and contributes nothing to spread.
Verify: Mean unchanged? New mean = 5 70 + 17.5 = 17.5 ✓. Variance dropped from 31.25 → 25.0 ✓. Mean imputation always shrinks variance — models become over-confident.
Worked example One giant value poisons the mean
Data: [12, 14, 15, NaN, 500]. The 500 is a genuine (rare) reading; the NaN is random.
Forecast: will mean or median give a fill closer to the "typical" 12–15 cluster?
Step 1 — Mean of observed: x ˉ = 4 12 + 14 + 15 + 500 = 4 541 = 135.25 .
Why this step? The mean uses every value with equal weight, so the lone 500 drags it far above the crowd.
Step 2 — Median of observed: sort → [12, 14, 15, 500], middle two are 14 and 15, median = 2 14 + 15 = 14.5 .
Why this step? The median only cares about position , not magnitude, so the 500 sits at the end and barely moves the middle. This is exactly why the parent says median minimizes ∑ ∣ x i − c ∣ (least absolute deviation) — absolute distance doesn't reward chasing outliers.
Verify: 135.25 lies outside the 12–15 cluster; 14.5 sits inside it ✓. For skewed data or outliers, use the median.
Worked example Delete rows, count the damage
Data: the parent's patient table.
ID
Age
Income
BP
1
45
60k
120
2
52
NaN
130
3
38
NaN
NaN
4
61
80k
140
Forecast: how many rows survive listwise deletion, and what does the surviving average Age become?
Step 1 — Keep only rows with no NaN anywhere. Rows 1 and 4 survive; 2 and 3 die. That's 2/4 = 50% data loss.
Why this step? Listwise deletion is all-or-nothing per row — one hole kills the whole row.
Step 2 — Compare average Age before vs after.
All four ages: 4 45 + 52 + 38 + 61 = 49.0 .
Survivors only: 2 45 + 61 = 53.0 .
Why this step? If younger patients skip Income (MAR), deletion systematically removes the young — mean age drifts up from 49 to 53. Your dataset now over-represents older people, which is bias you injected yourself.
Verify: 49.0 → 53.0 , an upward shift of 4 years ✓. Under MAR, deletion is not neutral.
Worked example Borrow from your neighbours, not the crowd
Data: Weight missing for patient A.
Patient
Height
Weight
Age
A
170
NaN
30
B
168
70
28
C
172
75
32
D
165
65
45
Forecast: which two patients look most like A, and will KNN give a weight above or below the global mean of 70?
Step 1 — Distance to each patient, ignoring the missing feature (Weight).
Distance = straight-line gap in the Height–Age plane: d ( A , i ) = ( Δ Height ) 2 + ( Δ Age ) 2 .
d ( A , B ) = ( 170 − 168 ) 2 + ( 30 − 28 ) 2 = 4 + 4 = 8 ≈ 2.83
d ( A , C ) = ( 170 − 172 ) 2 + ( 30 − 32 ) 2 = 4 + 4 = 8 ≈ 2.83
d ( A , D ) = ( 170 − 165 ) 2 + ( 30 − 45 ) 2 = 25 + 225 = 250 ≈ 15.81
Why this step? "Similar people have similar weight." We measure similarity as closeness in feature space — the figure shows A hugging B and C while D floats far off in the Age direction.
Step 2 — Pick K = 2 nearest → B and C (both ≈ 2.83 ; D at 15.8 is far).
Step 3 — Average their weights (uniform weights).
Weight A = 2 70 + 75 = 72.5 kg
Why this step? We exclude D entirely, so its low weight (65) can't drag our guess down. The global mean 3 70 + 75 + 65 ≈ 70 would.
Verify: KNN gives 72.5 vs global mean ≈ 70 ✓; KNN is pulled toward the two similar patients ✓. KNN keeps the Height–Weight relationship that mean imputation destroys.
Worked example Carry the last price — and see it fail
Data: daily stock price [100, 105, NaN, NaN, 112].
Forecast: what do the two holes get filled with, and by how much does forward fill undershoot the last real value 112?
Step 1 — Forward fill: each hole copies the last known value.
Last known before the gap is 105, so both holes get 105 → [100, 105, 105, 105, 112].
Why this step? Time series have autocorrelation — today ≈ yesterday. Carrying 105 forward beats a global mean.
Step 2 — Measure the error against the true trend.
A straight line from 105 (day 2) to 112 (day 5) would place day 3 at 105 + (112−105)/3 ≈ 107.33 and day 4 at ≈ 109.67. Forward fill kept both at 105 — flat during a clear climb.
Undershoot on day 4: 109.67 − 105 = 4.67 .
Why this step? To expose forward fill's blind spot: it freezes the series, so a rising trend is systematically under-filled. See the amber flat segment sitting below the cyan trend line.
Verify: both holes = 105 ✓; flat fill sits below the linear guess (undershoot ≈ 4.67) ✓. Forward fill fails on long or trending gaps.
Worked example You cannot average a colour
Data: favourite fruit [apple, banana, apple, NaN, apple, banana].
Forecast: what fills the hole — and why is "mean" not even an option?
Step 1 — Count each category. apple ×3, banana ×2.
Why this step? Categories have no order and no arithmetic — you cannot add "apple + banana", so mean and median are meaningless. The only central tendency left is the mode = most frequent value.
Step 2 — Fill with the mode = apple. → [apple, banana, apple, apple, apple, banana].
Verify: apple count 3 > banana count 2, so mode = apple ✓. Categorical → mode, always.
Worked example Nothing to borrow from
Data: column Cholesterol = [NaN, NaN, NaN, NaN].
Forecast: can any imputation method save this column?
Step 1 — Try mean: mean of observed values, but there are zero observed values → 0 sum of nothing = undefined.
Why this step? Every method (mean, median, KNN, MICE) borrows information from observed entries. With none, there is nothing to borrow.
Step 2 — The only honest action: drop the column. It carries zero information.
Why this step? Fabricating a constant (e.g. 0) would inject a fake signal the model might latch onto — worse than deleting. This connects to detecting such empty columns before modelling.
Verify: observed count = 0 ⇒ mean undefined (division by zero) ⇒ column must be dropped ✓.
Worked example KNN with a single friend is just copying
Data: same table as C4, but suppose only patient B has a recorded Weight (C and D are NaN too).
Forecast: with K = 1 , what does A's imputed weight equal?
Step 1 — Only B is a valid neighbour (C, D have no weight to give).
Step 2 — Weighted average of a single value = that value.
Weight A = w B w B ⋅ 70 = 70
Why this step? Any weight w B cancels top and bottom. With one neighbour, KNN collapses into copy-the-nearest . No smoothing, high variance — one weird neighbour becomes your answer.
Verify: w B w B ⋅ 70 = 70 for any w B = 0 ✓. Small K ⇒ noisy, brittle imputation.
Worked example Income missing for the young
A bank surveys customers. 40% of under-25s left Income blank ; over-25s almost always answered. You want a model for loan approval. Which strategy?
Forecast: deletion, mean, or conditional — and what's the risk of the wrong choice?
Step 1 — Identify the mechanism. Missingness depends on Age , an observed variable → this is MAR , not MCAR.
Why this step? MAR tells us the observed variables (Age) carry the information to reconstruct the hole honestly.
Step 2 — Reject deletion. Deleting blank-Income rows removes ~40% of the young → the model barely sees young customers (exactly the C3 bias). Reject.
Step 3 — Reject plain mean. One global income ignores that young people earn less on average → over-estimates their income → wrongly approves loans. Reject.
Step 4 — Choose conditional imputation (KNN or MICE) that predicts Income from Age and other features. It restores the age–income relationship.
Why this step? Under MAR, conditioning on the observed cause removes the bias. This is the parent's core lesson: the mechanism picks the method.
Verify: mechanism = MAR (depends on observed Age) ⇒ conditional imputation is the unbiased choice ✓.
Worked example Where do you compute the mean?
You will split data into train and test (split note ), then mean-impute a feature. Question: do you compute the imputation mean from (a) the whole dataset or (b) the training set only ?
Forecast: which is correct, and what breaks if you pick wrong?
Step 1 — Recall the rule: the test set must simulate unseen future data . Any statistic touching test rows before evaluation is data leakage .
Step 2 — Compute the mean on train only, then apply that same number to fill holes in both train and test.
Why this step? If you averaged over all data, the test rows influenced the fill value — the model peeks at the test set, and your reported accuracy is optimistically inflated.
Tiny numbers: train Income [40, 60, NaN] → train mean of observed = 2 40 + 60 = 50 . Test row with NaN gets filled with 50 , not with any test-derived number.
Verify: train mean = 2 40 + 60 = 50 , applied to the test hole ✓. Fit imputers on train, transform everywhere.
Recall Why does mean imputation shrink variance?
Because the fill value sits exactly at the mean, adding zero distance-from-mean, which dilutes the average squared distance. ::: A value at the balance point contributes 0 to the spread, so average spread drops.
Recall Under MAR, why is deletion biased but conditional imputation not?
Deletion removes rows non-randomly (e.g. the young), skewing the sample. ::: Conditioning on the observed cause (Age) reconstructs the missing values honestly.
Recall With
K = 1 , KNN imputation equals what?
A direct copy of the single nearest neighbour's value (weights cancel). ::: w w ⋅ v = v .
Recall On which set do you compute an imputation statistic to avoid leakage?
The training set only, then apply it to both train and test. ::: Fit on train, transform everywhere.
Mnemonic Picking a method in one breath
"Random & symmetric → Mean. Outliers → Median. Categories → Mode. Correlated → KNN/MICE. Time → Fill. Empty column → Drop."
Related: Outlier handling · Feature scaling · Parent: Handling Missing Values .