Variation
Mean Absolute Deviation
Measure spread as the average absolute distance each value sits from the
mean. Compute the mean, then average the absolute deviations — dividing by
n (not n−1). By hand, two loops: one for the mean, one for the sum of
absolute deviations. With numpy, np.mean(np.abs(x - np.mean(x))) does
both in one vectorised expression.
By hand
First loop: accumulate total for the mean. Second loop: accumulate
abs_sum = sum(abs(v - mean)). Divide by n (total count, no Bessel
correction — MAD uses n by definition). With mean=8.0 and absolute
deviations [4, 0, 2, 5, 2, 2, 1] summing to 16, MAD = 16/7 ≈ 2.2857.
values = [4, 8, 6, 13, 10, 6, 9]
n = len(values)
total = 0.0
for v in values:
total = total + v
mean = total / n
abs_sum = 0.0
for v in values:
abs_sum = abs_sum + abs(v - mean)
mad = abs_sum / n
print('RESULT:', round(mad, 10))
values ← [4, 8, 6, 13, 10, 6, 9]
1values = [4, 8, 6, 13, 10, 6, 9]2n = len(values)values this step[4, 8, 6, 13, 10, 6, 9]valuesn ← 7
1values = [4, 8, 6, 13, 10, 6, 9]2n = len(values)3total = 0.0values this step7ntotal ← 0.0
2n = len(values)3total = 0.04for v in values:values this step0.0totalv ← 4, total ← 4.0
pass 1 of 73total = 0.04for v in values:5 total = total + v6mean = total / nvalues this step4v0.0 → 4.0totalAll 7 passes — pass 1 is the card above pass vtotal1 4 0.0 → 4.0 2 4 → 8 4.0 → 12.0 3 8 → 6 12.0 → 18.0 4 6 → 13 18.0 → 31.0 5 13 → 10 31.0 → 41.0 6 10 → 6 41.0 → 47.0 7 6 → 9 47.0 → 56.0 for v in values:
3total = 0.04for v in values:5 total = total + vmean ← 8.0
5 total = total + v6mean = total / n7abs_sum = 0.0values this step8.0meanabs_sum ← 0.0
6mean = total / n7abs_sum = 0.08for v in values:values this step0.0abs_sumv ← 4, abs_sum ← 4.0
pass 1 of 77abs_sum = 0.08for v in values:9 abs_sum = abs_sum + abs(v - mean)10mad = abs_sum / nvalues this step9 → 4v0.0 → 4.0abs_sumAll 7 passes — pass 1 is the card above pass vabs_sum1 9 → 4 0.0 → 4.0 2 4 → 8 — 3 8 → 6 4.0 → 6.0 4 6 → 13 6.0 → 11.0 5 13 → 10 11.0 → 13.0 6 10 → 6 13.0 → 15.0 7 6 → 9 15.0 → 16.0 for v in values:
7abs_sum = 0.08for v in values:9 abs_sum = abs_sum + abs(v - mean)mad ← 2.2857142857142856
9 abs_sum = abs_sum + abs(v - mean)10mad = abs_sum / n11print('RESULT:', round(mad, 10))values this step2.2857142857142856madstdout ← RESULT: 2.2857142857
10mad = abs_sum / n11print('RESULT:', round(mad, 10))values this stepRESULT: 2.2857142857stdout
With the library
np.abs(x - x_mean) subtracts the mean from every element and takes the
absolute value in one vectorised step; np.mean(...) then averages the
result. Both halves divide by n, so the results match exactly.
import numpy as np
from dalib.display import set_display
set_display()
values = [4, 8, 6, 13, 10, 6, 9]
x = np.array(values, dtype=float)
x_mean = float(np.mean(x))
mad = float(np.mean(np.abs(x - x_mean)))
print('mean:', x_mean)
print('RESULT:', round(mad, 10))
mean: 8.0
RESULT: 2.2857142857
Implementation notes
- MAD divides by n (the full count), not n−1. There is no Bessel correction because MAD is not trying to estimate a population parameter in the same way variance is.
- MAD is in the same units as the data (like std) but is more robust to outliers because absolute differences grow linearly while squared differences grow quadratically.
statistics.mean(abs(v - mean) for v in values)is the pure-stdlib equivalent, but numpy's vectorised form is faster for large arrays.