Skip to content

Beginner: data foundations · Statistics made simple · topic 9 of 62 · 30 min

The normal distribution and z-scores

Explanation

Many measurements pile up in a symmetric bell shape called the normal distribution. In it, about 68% of values lie within 1 standard deviation of the mean, 95% within 2 and 99.7% within 3. A z-score says how many standard deviations a value is from the mean, which lets you compare scores from different tests fairly.

Why one curve shows up everywhere

Measure the heights of thousands of adults, the weights of 1-kg rice packets from a factory, or small errors in a scale, and draw how often each value occurs. You often get the same shape: a single hump in the middle that falls away evenly on both sides, like a bell. This is the normal distribution (also called the Gaussian or bell curve). It appears when a value is the result of many small, independent influences adding up.

Its features

  • It is symmetric: the left half mirrors the right half.
  • The mean, median and mode are all at the centre.
  • Two numbers describe it completely: the mean (where the centre is) and the standard deviation (how wide the bell is).
  • The tails go on forever but get very thin: values far from the mean are rare, not impossible.
Careful: Not everything is normal. Incomes, house prices and website visits are strongly right-skewed. Before using normal-curve rules, draw a histogram (Module 4) and check the shape.

The 68–95–99.7 rule

For normal data, about 68% of values lie within 1 SD of the mean, about 95% within 2 SDs, and about 99.7% within 3 SDs. Suppose adult heights in a group are normal with mean 165 cm and SD 7 cm. Then about 68% are between 158 and 172 cm, about 95% between 151 and 179 cm, and almost everyone (99.7%) between 144 and 186 cm.

python
from statistics import NormalDist

heights = NormalDist(mu=165, sigma=7)
print(round(heights.cdf(172) - heights.cdf(158), 4))   # 0.6827
print(round(heights.cdf(179) - heights.cdf(151), 4))   # 0.9545
print(round(heights.cdf(172), 4))                      # 0.8413
cdf(x) is the share of values at or below x. The exact shares behind the rule are 68.27%, 95.45% and 99.73%. About 84% of people are 172 cm or shorter.

z-scores

A z-score (or standard score) measures how far a value is from the mean in units of standard deviation. In words: subtract the mean, then divide by the SD. The formula is z = (x − mean) / sd. A z of 0 is exactly average, +1 is one SD above, −2 is two SDs below. Because z has no units, you can compare things measured on completely different scales.

python
marks = [55, 60, 65, 70, 75, 80, 85]
mean = sum(marks) / len(marks)                                   # 70.0
sd = (sum((m - mean) ** 2 for m in marks) / len(marks)) ** 0.5   # 10.0
print([(m - mean) / sd for m in marks])
# [-1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5]
Each mark expressed as "how many SDs from the class average", using the population SD.

Comparing scores from different exams

Ravi scored 82 out of 100 in his board exam, where the mean was 70 and the SD was 8. In a mock entrance test he scored 180 out of 300, where the mean was 120 and the SD was 50. (Made-up numbers.) Which was the stronger performance? Raw marks cannot be compared, but z-scores can: board z = (82 − 70) / 8 = 1.5; mock z = (180 − 120) / 50 = 1.2. Relative to the other students, his board result was stronger.

Think of it like this: z-scores are like converting prices from rupees, dollars and euros into one currency before comparing them. The SD is the exchange rate that turns "marks in this exam" into a common unit.
python
from statistics import NormalDist

board = NormalDist(mu=70, sigma=8)
print(board.zscore(82))                       # 1.5
print(round(board.cdf(82), 4))                # 0.9332
print(round(NormalDist().inv_cdf(0.975), 2))  # 1.96
zscore needs Python 3.9 or newer. If board marks were normal, about 93% of students scored 82 or less. inv_cdf goes the other way: 97.5% of a standard normal lies below z = 1.96, which you will meet again in Module 3.

Flagging unusual values

Since about 95% of normal data has |z| ≤ 2 (|z| means the size of z, ignoring the sign), values with |z| > 2 are often flagged as unusual, and |z| > 3 as very unusual. This is a quick check, with two catches. In a big dataset about 5% of perfectly normal values have |z| > 2, so "unusual" is not "wrong". And a huge outlier inflates the SD itself, which can hide other outliers. For skewed data the 1.5 × IQR rule from the previous topic is safer.

Common mistakes

  • Applying the 68–95–99.7 rule to skewed data. Fix: check the shape first.
  • Forgetting that z can be negative. A z of −2 is as unusual as +2. Fix: compare abs(z).
  • Dividing by zero when every value is the same (SD = 0). Fix: handle that case separately; all z-scores are then 0.
  • Calling every |z| > 2 point an error. Fix: treat it as a flag to investigate.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

The normal distribution and z-scores · 1/7

Normal distribution · z-scores

In this lesson you will meet the bell curve and the z-score, a way to compare values on different scales.

Prefer a video by a teacher? Find free videos on “normal distribution 68 95 99.7 rule z score explained” on YouTube ↗

In real life: Normalised scores in multi-shift exams

When a large exam is held in several shifts with different papers, one shift's paper may be harder than another's. Examining bodies in India use normalisation methods (for example percentile-based scores) so that candidates are compared fairly across shifts. The idea is the same as a z-score: judge each score against the other candidates who sat the same paper. The exact formula differs by exam, so check the official information bulletin.

python
shift1 = {"mean": 62, "sd": 12}   # made-up shift statistics
shift2 = {"mean": 48, "sd": 10}

z_asha = (80 - shift1["mean"]) / shift1["sd"]
z_vikram = (70 - shift2["mean"]) / shift2["sd"]
print(round(z_asha, 2), round(z_vikram, 2))
Output: 1.5 2.2. Vikram scored fewer raw marks, but did better relative to his shift.

Practice (0/3 done)

Task 1 · Code · Python

Write z_score(x, mean, sd) that returns (x − mean) / sd rounded to 2 decimal places. Example: z_score(82, 70, 8) returns 1.5.

Task 2 · Code · Python

Write z_scores(values) that returns a list with the z-score of each value, rounded to 2 decimal places, using the mean and the POPULATION standard deviation of the list. If the SD is 0 (all values equal), return a list of 0.0 for each value. Return [] for an empty list.

Task 3 · Code · Python

Write flag_unusual(values) that returns the values whose z-score (population SD) has absolute value greater than 2, in their original order. If there are fewer than 2 values or the SD is 0, return [].

Quick quiz

Question 1

1.For normal data with mean 50 and SD 5, about what share of values lies between 40 and 60?

Question 2

2.In an exam with mean 60 and SD 10, what is the z-score of 45?

Question 3

3.Asha has z = 1.8 in maths and z = 0.9 in English. What can you say?

Question 4

4.Which data is least likely to be close to normal?

Question 5

5.What does NormalDist(mu=70, sigma=8).cdf(82) return (about 0.93)?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

For normal data with mean 50 and SD 5, about what share of values lies between 40 and 60?

Answer: 95%

40 and 60 are 2 SDs from the mean, and about 95% of normal data lies within 2 SDs.

In an exam with mean 60 and SD 10, what is the z-score of 45?

Answer: -1.5

z = (45 − 60) / 10 = −1.5: one and a half SDs below the mean.

Asha has z = 1.8 in maths and z = 0.9 in English. What can you say?

Answer: Relative to her classmates, she did better in maths than in English

z compares each score with its own class; it says nothing about raw marks or difficulty. 0.9 is still above average.

Which data is least likely to be close to normal?

Answer: Monthly incomes of people in a city

Incomes are strongly right-skewed: most are moderate and a few are very large.

What does NormalDist(mu=70, sigma=8).cdf(82) return (about 0.93)?

Answer: The share of values at or below 82

cdf (cumulative distribution function) gives the probability of a value at or below x. About 93% would score 82 or less.

Delivery times have a variance of 49 square minutes. What is the standard deviation?Related

Answer: 7 minutes

The SD is the square root of the variance: √49 = 7, back in minutes.

From Spread: range, variance and standard deviation

If you collect 4 times as much data, the standard error becomes…Related

Answer: Half as big

SE = s ÷ √n, and √4 = 2, so the SE halves.

From Samples, the central limit theorem and confidence intervals

Where should the scaler learn its mean and standard deviation?Related

Answer: From the training data only

Anything else leaks test information.

From Scaling and transforming numbers

With +4 and -1 marking, what is the score for 10 correct, 5 wrong and 5 skipped?Related

Answer: 35

10 × 4 = 40, minus 5 × 1 = 5, gives 35. Skipped questions add nothing.

From Project: quiz game with negative marking

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 1 more topic in “Statistics made simple” before its exam: Correlation: how two things move together.
  2. Module 2 exam: Statistics made simple · 14 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, Probability and inference. 62 topics left in the course before the final exam.

← Previous: Percentiles, quartiles and outliers