23 · The Z-test
When σ is known and n is large, compare a sample mean to a hypothesised population mean using a single elegant ratio: z = (x̄ − μ₀) / (σ / √n).
When σ is known and n is large, the Z-test compares a sample mean to a hypothesized population mean — the simplest formal test.
Without this:
Without it, you can't ask 'is this sample's mean significantly different from a known reference?'
In the previous lesson you learned that the p-value measures how surprising your data is under H₀. Now it's time to build the first concrete test that produces that p-value: the one-sample Z-test.
The recipe:
Given a sample of n observations with sample mean x̄, and assuming the population standard deviation σ is known, test H₀: μ = μ₀ using the Z-statistic:
z = (x̄ − μ₀) / (σ / √n)
Under H₀, z follows a Standard Normal N(0, 1) — because by the CLT the sample mean is approximately N(μ₀, σ²/n), so subtracting the mean and dividing by the SE gives a standard Normal.
One-tailed vs two-tailed p-values:
- Two-tailed (H₁: μ ≠ μ₀): p = 2 · (1 − Φ(|z|)) — you're equally surprised by extreme values in either direction.
- One-tailed right (H₁: μ > μ₀): p = 1 − Φ(z)
- One-tailed left (H₁: μ < μ₀): p = Φ(z)
where Φ is the standard Normal CDF.
Assumptions:
- σ is known (from theory, historical data, or a very large previous study).
- Either n is large (≥ 30 by rule of thumb) so the CLT kicks in, or the population is already Normal.
- Observations are iid.
scipy note: scipy doesn't ship a dedicated ztest function. The standard approaches are statsmodels.stats.weightstats.ztest or hand-rolling it with scipy.stats.norm — which is what we'll do here since it makes the math transparent.
Python (in browser)
One-sample Z-test: 50 IQ scores from N(102, 15) tested against H₀: μ=100. Because the true mean is only 2 points above the null and n is modest, the test may or may not reject — giving us a concrete feel for statistical power.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Python (in browser)
Two-sample Z-test comparing two groups where both σ's are assumed known. The true effect is 5 IQ points; whether that's detectable depends on both the sample size and random chance in this draw.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Python (in browser)
Power analysis: to reliably detect a 5-point IQ shift with σ=15 at 80% power and α=0.05, you need ~71 observations per group.
Python runs entirely in your browser via Pyodide (~6 MB on first Run, cached after).
Z-test assumptions checklist and scipy/statsmodels options.
For a two-tailed Z-test at α = 0.05, what is the critical z-value (i.e., you reject H₀ if |z| exceeds it)?
- **Z-statistic:** z = (x̄ − μ₀) / (σ/√n). Under H₀ this is N(0,1). Two-tailed p = 2·(1 − Φ(|z|)).
- Use Z-test only when σ is known AND n ≥ 30 (or data is Normal). Otherwise use the t-test.
- **Power formula:** n = ((z_{α/2} + z_β) · σ / Δ)². At α=0.05, power=0.80: z_{α/2}=1.96, z_β=0.84.
Comparing observed conversion rate to a target benchmark (Z-test on proportions); large-sample A/B tests with known variance; significance flags in monitoring dashboards.
If you remove it: You can't make formal claims about 'sample mean differs from reference' without a Z-test or its t-equivalent.