Index Ai Academy
Phase 0 · Tools · Numbers for code

Averages and spread

Mean, median and standard deviation, built by hand, and which one a question needs.

About 25 minutes · Free lesson

Start this lesson

Why it matters

Data rarely arrives as one number. Delivery times, order values, a model's scores on a test: they come as lists, and you need to say what's typical and how much the values vary. The mean, the median and the standard deviation are the three numbers people reach for, and each one has a trap. One huge order can drag the "average" order value far from any real order, and two products can share an average and behave nothing alike. This lesson builds each one by hand in Python, so you know exactly what a library means when it reports them.

What you'll be able to do

  • Compute a mean and a median by hand in Python, and say which one a situation needs
  • Explain how one extreme value pulls the mean but not the median
  • Measure spread with the range and the standard deviation
  • Read a result like "82% ± 3" and spot a suspicious average

What it covers

  1. The mean: share it out equally
  2. The median: the middle value
  3. The median of an even count
  4. Percentiles: the median's family
  5. Mean or median?
  6. Spread: how far from the middle?
  7. Standard deviation by hand
  8. Reading spread in results
  9. Averages in AI
Quick check
Before any explaining, a guess. Five orders came in today. What does this print?
orders = [20, 25, 30, 25, 400]
print(sum(orders) / len(orders))
  1. 500
  2. 30.0
  3. 100.0
  4. 25.0
Show the answer

100.0

The five orders add up to 500, and 500 / 5 = 100.0. One $400 order pulls the average far above every other order. That's the first trap of averages, and this lesson's starting point.

The mean: share it out equally

The mean is what most people call "the average": add everything up and divide by how many there are. Think of it as sharing out equally. If five friends' restaurant bills add up to $100, the mean is what each would pay if they split it evenly: $20.

bills = [18, 25, 12, 30, 15]
mean = sum(bills) / len(bills)
print(mean)
It runs right here in your browser, with nothing to install.

The mean has a useful property: the mean times the count gives back the total. That makes it the right choice when you care about totals, like revenue per customer to plan next month's revenue. Its weakness is that every value pulls on it, and extreme values pull hardest. One $400 order among $25 ones moves the mean a long way, as the opening question showed. And an empty list has no mean at all: sum([]) / len([]) divides by zero, so code that averages data it didn't check first can crash on a quiet day.

Try it now

Every order but one is the typical size. Drag the big one and watch the mean chase it while the median stays put.

The median: the middle value

The median is the middle value once the list is sorted. Half the values are below it and half above. It doesn't care how extreme the extremes are: make the biggest order $400 or $4 million, and the median doesn't move.

times = [12, 3, 7, 30, 5]
in_order = sorted(times)
print(in_order)
middle = len(in_order) // 2
print(in_order[middle])

With an odd count there's one middle value: for five values it's at position 2, which is len // 2. With an even count there are two middle values, and the median is the mean of those two. That's why house prices and salaries are usually reported as medians: a few mansions or one very rich founder can't distort them.

Quick check
What does this print?
times = sorted([12, 3, 7, 30, 5])
print(times[len(times) // 2])
  1. 11.4
  2. 30
  3. 12
  4. 7
Show the answer

7

Sorted, the list is [3, 5, 7, 12, 30]. There are 5 values, so the middle position is 5 // 2 = 2, which holds 7. The 30 doesn't drag it up.

Drill

The median of an even count

Six parcels took these delivery times in hours: 34, 12, 27, 19, 45 and 22. With an even count, the median is the mean of the two middle values. Set in_order to the sorted list and median to the median.

hours = [34, 12, 27, 19, 45, 22]

in_order = hours    # sort it
median = 0          # the mean of the two middle values

print(in_order, median)
In the lesson, your code is checked as you write it.

Percentiles: the median's family

The median is one of a family called percentiles. The 90th percentile is the value that 90% of the data falls below; the median is the 50th. Percentiles describe the slow end of response times well: "half our replies arrive within 2 hours, and 95% within 6" says far more than a single average.

Quick check
A support team's replies have a median of 2 hours and a 95th percentile of 6 hours. What does the 6 tell you?
  1. 95% of replies arrived within 6 hours
  2. 95 replies took 6 hours each
  3. The average reply took 6 hours
  4. 6% of replies arrived late
Show the answer

95% of replies arrived within 6 hours

The 95th percentile is the value that 95% of the data falls below, so all but the slowest 5% of replies came within 6 hours.

Mean or median?

Neither is "the right average"; they answer different questions. The mean answers "if it were shared out equally, how much each?", which is what you need for totals and budgets. The median answers "what's a typical one like?", which is what you need when a few extreme values would mislead.

When the two are close, the data is fairly balanced. When the mean is far above the median, a few large values are pulling it up; that's called a skewed distribution, and it's common in money, waiting times and website traffic. Reporting both, side by side, tells a reader more than either alone. (A third average, the mode, is the most common value. It's handy for categories, like the most popular shirt size.)

Spread: how far from the middle?

Two shops both average 40 minutes to deliver. At the first, every delivery takes 38 to 42 minutes. At the second, some take 10 and some take 70. Same mean, very different experience. The spread says how far values typically sit from the middle.

The simplest measure is the range, max minus min, but one odd value can make it huge. The usual measure is the standard deviation: roughly, the typical distance from the mean. You find each value's distance from the mean, square the distances (so negatives don't cancel), average the squares, and take the square root to get back to the original units:

values = [38, 40, 42, 40]
mean = sum(values) / len(values)
total = 0
for v in values:
    total = total + (v - mean) ** 2
std = (total / len(values)) ** 0.5
print(mean, round(std, 2))

The average of the squared distances, before the square root, is called the variance. (Statisticians often divide by one less than the count when the list is a sample from a bigger group; the idea is the same.)

Quick check
Two products both average 4 stars. Product A's ratings are all 4s; product B's are half 5s and half 3s. Which has the bigger standard deviation?
  1. Both, equally, since the averages match
  2. B: its ratings sit further from the average
  3. A: it has more ratings at exactly 4
  4. Neither: ratings don't have a spread
Show the answer

B: its ratings sit further from the average

A's ratings are all exactly the mean, so its standard deviation is 0. B's are each 1 star away, so its standard deviation is 1. Same mean, different spread.

Drill

Standard deviation by hand

Five test runs scored 4, 8, 6, 5 and 7. Set mean, then variance (the average of the squared distances from the mean), then std (its square root), with std rounded to 2 decimal places. Use a loop to add up the squared distances.

scores = [4, 8, 6, 5, 7]

mean = 0
variance = 0
std = 0

print(mean, variance, std)
In the lesson, your code is checked as you write it.

Reading spread in results

For data shaped like a bell, a handy rule: about two thirds of the values sit within one standard deviation of the mean, and about 95% within two. So a report like "delivery takes 40 ± 5 minutes" says most deliveries take 35 to 45 minutes, and almost all take 30 to 50. A value three standard deviations out is rare enough to investigate.

The same notation shows up in AI results: "82% ± 3" means a model scored 82% on average across several runs, with a standard deviation of 3 points. If a new model scores 84% ± 3, the gap is smaller than the run-to-run wobble, and you can't yet claim it's better.

Quick check
An eval has 50 questions. A model scored 41 on Monday and 45 on Tuesday. Using rates from the fractions lesson, what does this print?
monday = 41 / 50 * 100
tuesday = 45 / 50 * 100
print((monday + tuesday) / 2)
  1. 172.0
  2. 86.0
  3. 43.0
  4. 88.0
Show the answer

86.0

The two days scored 82% and 90%, and their mean is 86.0. Averaging rates is fine here because both days had the same 50 questions; with different-sized groups you'd combine the counts first.

Averages in AI

These three numbers are everywhere in the course. An eval's accuracy is a mean of 1s and 0s. A model's loss is a mean of its errors over a batch of examples. Results are reported as mean ± standard deviation across runs. Response times are reported as a median, plus a slow percentile such as the 95th, because a mean hides the slow tail. And in Phase 4, normalization layers subtract a mean and divide by a standard deviation inside the network itself.

Python's statistics module has mean(), median() and stdev() built in, and you'll meet it in the modules lesson. Having built each one by hand, you'll know exactly what they compute, and when one of them is the wrong number for the question.

Quick check
A model scored 0.8, 0.9 and 0.7 on three test sets. What does this print?
scores = [0.8, 0.9, 0.7]
print(round(sum(scores) / len(scores), 2))
  1. 0.9
  2. 0.8
  3. 0.85
  4. 2.4
Show the answer

0.8

The scores add up to 2.4 (give or take a tiny float error), and 2.4 / 3 = 0.8. round(..., 2) tidies the float noise away.

Quick check
A support team's median reply time is 2 hours, but the mean is 9 hours. What does that tell you?
  1. Most replies took about 9 hours each
  2. The team answers every message in 2 hours
  3. The data must be wrong, since they differ
  4. A few replies took far longer than the rest
Show the answer

A few replies took far longer than the rest

Half the replies came within 2 hours, but a few very slow ones pulled the mean up to 9. The gap between mean and median is a sign of skew.

Practice what you just read

  • 3 code examples you can edit and run
  • a practice exercise that checks your code
  • a 6-question quiz
  • 5 review cards for spaced repetition

Start this lesson

Try a quiz question

Most homes in a town sell for about $300,000, but three mansions sold for $9 million each. Which number best describes a typical home?

  1. The median price
  2. The mean price
  3. The highest price
  4. The total of all prices

Answer it at the end of the lesson to see if you're right, and why.

Before this lesson