03-02: Weighted and Grouped Means¶
Sometimes the values you are averaging do not count equally, or you no longer have the raw values at all — only a frequency table. Both situations have their own formula, and both are standard exam material.
The Weighted Mean¶
When each value carries a weight w (credit hours, quantity sold, group size, importance):
Σ (w · x) w₁x₁ + w₂x₂ + … + wₙxₙ
x̄_w = ───────── = ───────────────────────────
Σ w w₁ + w₂ + … + wₙ
The ordinary mean is the special case where every weight equals 1.
Worked example — GPA¶
| Course | Grade points x |
Credit hours w |
w · x |
|---|---|---|---|
| Statistics | 4.0 (A) | 3 | 12.0 |
| Biology | 3.0 (B) | 4 | 12.0 |
| English | 2.0 (C) | 3 | 6.0 |
| Lab | 4.0 (A) | 1 | 4.0 |
| Total | 11 | 34.0 |
The unweighted mean of 4.0, 3.0, 2.0, 4.0 is 3.25 — wrong, because it treats the 1-credit lab as equal to the 4-credit biology course.
Worked example — combining group means¶
Three sections with different sizes:
| Section | n |
Mean score |
|---|---|---|
| A | 30 | 82 |
| B | 25 | 76 |
| C | 45 | 88 |
Overall mean = (30·82 + 25·76 + 45·88) / (30 + 25 + 45)
= (2460 + 1900 + 3960) / 100
= 8320 / 100
= 83.2
The plain average of 82, 76, 88 is 82.0 — the third section's 45 students are undercounted.
Warning
Never average averages unless every group has the same size. This is the single most common weighted-mean error, and it appears constantly in reports on regional sales, per-store margins, and course grades.
The Mean from a Frequency Distribution (Grouped Data)¶
When you only have a frequency table, you no longer know the exact values. Assume every value in a class sits at the class midpoint Xm:
This is an approximation. It is exact only if the values happen to be symmetric within every class.
The grouped variance and standard deviation¶
The matching spread formulas (used again in 04-01):
Definition form s² = Σ f (Xm − x̄)² / (n − 1)
Computation form s² = [ Σ f·Xm² − ( (Σ f·Xm)² / n ) ] / (n − 1)
s = √s²
Worked example¶
Service times from 02-01:
| Class | f |
Xm |
f · Xm |
Xm − x̄ |
f (Xm − x̄)² |
|---|---|---|---|---|---|
| 20–29 | 3 | 24.5 | 73.5 | −16.4 | 806.9 |
| 30–39 | 8 | 34.5 | 276.0 | −6.4 | 327.7 |
| 40–49 | 9 | 44.5 | 400.5 | 3.6 | 116.6 |
| 50–59 | 5 | 54.5 | 272.5 | 13.6 | 924.8 |
| Total | 25 | 1022.5 | 2176.0 |
The exact mean of the 25 raw values is 41.2 — the grouped estimate of 40.9 is off by about 0.7%, which is typical.
The grouped median¶
(n/2 − CF)
median = L + ─────────────── × w
f
L = lower BOUNDARY of the median class
CF = cumulative frequency of all classes BEFORE the median class
f = frequency of the median class
w = class width
Find the median class first: the one where the cumulative frequency first reaches n/2.
n/2 = 12.5 → first class with cum f ≥ 12.5 is 40–49 (cum f = 20)
L = 39.5, CF = 11, f = 9, w = 10
median = 39.5 + ((12.5 − 11) / 9) × 10 = 39.5 + 1.67 = 41.17 minutes
The grouped mode (modal class)¶
d₁
mode = L + ─────────── × w
d₁ + d₂
L = lower boundary of the modal class (the class with the highest f)
d₁ = f_modal − f_previous
d₂ = f_modal − f_next
Modal class = 40–49 (f = 9); L = 39.5, d₁ = 9−8 = 1, d₂ = 9−5 = 4, w = 10
mode = 39.5 + (1 / 5) × 10 = 41.5 minutes
Other Means Worth Knowing¶
| Mean | Formula | Use for |
|---|---|---|
| Geometric | (x₁ · x₂ · … · xₙ)^(1/n) |
Growth rates, returns, index numbers |
| Harmonic | n / Σ(1/xᵢ) |
Average of rates over a fixed distance (speeds) |
For the same positive data: harmonic ≤ geometric ≤ arithmetic.
Why it matters: an investment that gains 50% then loses 50% has an arithmetic mean return of 0%, but you are down 25%. The geometric mean, √(1.50 × 0.50) − 1 = −13.4% per year, is the honest figure.
Excel¶
' ── Weighted mean ───────────────────────────────────────────────────
' Grade points in B2:B5, credit hours in C2:C5
=SUMPRODUCT(B2:B5, C2:C5) / SUM(C2:C5) ' GPA -> 3.09
' Combining group means: means in B2:B4, group sizes in C2:C4
=SUMPRODUCT(B2:B4, C2:C4) / SUM(C2:C4) ' overall mean -> 83.2
' ── Grouped mean, variance, SD ──────────────────────────────────────
' Lower limits D2:D5, upper limits E2:E5, frequencies F2:F5
=(D2+E2)/2 ' G2: class midpoint Xm
=F2*G2 ' H2: f · Xm
=SUM(H2:H5)/SUM(F2:F5) ' grouped mean x̄ -> 40.9
=F2*(G2-$J$1)^2 ' I2: f(Xm − x̄)² ($J$1 = x̄)
=SUM(I2:I5)/(SUM(F2:F5)-1) ' grouped variance -> 90.67
=SQRT(SUM(I2:I5)/(SUM(F2:F5)-1)) ' grouped SD -> 9.52
' Single-formula version (no helper columns)
=SUMPRODUCT(F2:F5,(D2:D5+E2:E5)/2)/SUM(F2:F5) ' mean
=SQRT(SUMPRODUCT(F2:F5,((D2:D5+E2:E5)/2-$J$1)^2)/(SUM(F2:F5)-1)) ' SD
' ── Grouped median ──────────────────────────────────────────────────
' L=39.5 (J3), CF=11 (J4), f=9 (J5), w=10 (J6), n=25 (J7)
=J3 + ((J7/2 - J4)/J5) * J6 ' -> 41.17
' ── Grouped mode ────────────────────────────────────────────────────
=J3 + (1/(1+4)) * J6 ' -> 41.5
' ── Other means ─────────────────────────────────────────────────────
=GEOMEAN(A2:A10) ' geometric mean
=HARMEAN(A2:A10) ' harmonic mean
=GEOMEAN(A2:A10)-1 ' average growth rate (on 1+r values)
R¶
# ── Weighted mean ──────────────────────────────────────────────────
points <- c(4.0, 3.0, 2.0, 4.0)
credits <- c(3, 4, 3, 1)
weighted.mean(points, w = credits) # 3.090909
sum(points * credits) / sum(credits) # same, done by hand
means <- c(82, 76, 88); sizes <- c(30, 25, 45)
weighted.mean(means, sizes) # 83.2
# ── Grouped data ───────────────────────────────────────────────────
lower <- c(20, 30, 40, 50)
upper <- c(29, 39, 49, 59)
f <- c(3, 8, 9, 5)
Xm <- (lower + upper) / 2 # 24.5 34.5 44.5 54.5
n <- sum(f) # 25
w <- 10
xbar <- sum(f * Xm) / n # 40.9
s2 <- sum(f * (Xm - xbar)^2) / (n - 1) # 90.67
s <- sqrt(s2) # 9.52
c(mean = xbar, var = s2, sd = s)
# Grouped median
cumf <- cumsum(f) # 3 11 20 25
k <- which(cumf >= n/2)[1] # index of the median class -> 3
L <- lower[k] - 0.5 # 39.5 (lower BOUNDARY)
CF <- if (k == 1) 0 else cumf[k - 1] # 11
med <- L + ((n/2 - CF) / f[k]) * w # 41.17
med
# Grouped mode
m <- which.max(f) # 3
d1 <- f[m] - if (m == 1) 0 else f[m - 1] # 1
d2 <- f[m] - if (m == length(f)) 0 else f[m + 1] # 4
mode_g <- (lower[m] - 0.5) + (d1 / (d1 + d2)) * w # 41.5
mode_g
# Reconstruct raw-ish data from a frequency table
raw <- rep(Xm, times = f)
mean(raw); sd(raw)
# ── Other means ────────────────────────────────────────────────────
geo <- function(x) exp(mean(log(x)))
harm <- function(x) length(x) / sum(1 / x)
geo(c(1.50, 0.50)) - 1 # -0.134 -> -13.4% per period
harm(c(60, 40)) # 48 km/h average speed
Python¶
import numpy as np
import pandas as pd
from scipy import stats
# ── Weighted mean ──────────────────────────────────────────────────
points = np.array([4.0, 3.0, 2.0, 4.0])
credits = np.array([3, 4, 3, 1])
np.average(points, weights=credits) # 3.0909...
means = np.array([82, 76, 88]); sizes = np.array([30, 25, 45])
np.average(means, weights=sizes) # 83.2
# ── Grouped data ───────────────────────────────────────────────────
lower = np.array([20, 30, 40, 50])
upper = np.array([29, 39, 49, 59])
f = np.array([3, 8, 9, 5])
Xm = (lower + upper) / 2
n = f.sum()
w = 10
xbar = np.average(Xm, weights=f) # 40.9
s2 = (f * (Xm - xbar) ** 2).sum() / (n - 1) # 90.67
s = np.sqrt(s2) # 9.52
# Grouped median
cumf = f.cumsum()
k = int(np.argmax(cumf >= n / 2))
L = lower[k] - 0.5
CF = cumf[k - 1] if k > 0 else 0
median_g = L + ((n / 2 - CF) / f[k]) * w # 41.17
# Grouped mode
m = int(f.argmax())
d1 = f[m] - (f[m - 1] if m > 0 else 0)
d2 = f[m] - (f[m + 1] if m < len(f) - 1 else 0)
mode_g = (lower[m] - 0.5) + (d1 / (d1 + d2)) * w # 41.5
# Reconstruct raw-ish data
raw = np.repeat(Xm, f)
raw.mean(), raw.std(ddof=1)
# ── Other means ────────────────────────────────────────────────────
stats.gmean([1.50, 0.50]) - 1 # -0.134
stats.hmean([60, 40]) # 48.0
Quick Reference¶
| Task | Excel | R | Python |
|---|---|---|---|
| Weighted mean | SUMPRODUCT(x,w)/SUM(w) |
weighted.mean(x, w) |
np.average(x, weights=w) |
| Grouped mean | SUMPRODUCT(f,Xm)/SUM(f) |
sum(f*Xm)/sum(f) |
np.average(Xm, weights=f) |
| Grouped variance | SUMPRODUCT(f,(Xm-x̄)^2)/(n-1) |
sum(f*(Xm-xbar)^2)/(n-1) |
(f*(Xm-xbar)**2).sum()/(n-1) |
| Grouped median | L+((n/2−CF)/f)*w |
same by hand | same by hand |
| Grouped mode | L+(d₁/(d₁+d₂))*w |
same by hand | same by hand |
| Geometric mean | GEOMEAN(range) |
exp(mean(log(x))) |
scipy.stats.gmean |
| Harmonic mean | HARMEAN(range) |
length(x)/sum(1/x) |
scipy.stats.hmean |
| Expand a freq table | manual | rep(Xm, times = f) |
np.repeat(Xm, f) |
Common Mistakes¶
- Averaging group averages without weighting by group size.
- Using class limits instead of boundaries in the grouped-median formula (
Lmust be a boundary). - Dividing the grouped variance by
nwhen the data is a sample — usen − 1. - Using the arithmetic mean for growth rates or investment returns; use the geometric mean.
- Forgetting that grouped statistics are estimates — if you still have the raw data, use it.
⬅️ Previous: 03-01: Mean, Median and Mode ➡️ Next: 04-01: Measures of Variation