Why the mean is not enough
A standard deviation is a number that says how far values usually sit from their mean. You need it because two data sets can share a mean and still behave very differently.
Two bike stations can both hire 240 bikes a day on average. One may hire close to 240 every day. The other may swing between 100 and 380.
By the end of this lesson
Note
I can summarise data with a centre and a spread.
Key words
| Word | What it means | Example |
|---|---|---|
| Mean | the total of the values divided by how many there are | |
| Spread | how far apart the values are | |
| Quartile | a value that cuts ordered data into quarters | the first quartile |
| Variance | the mean of the squared gaps from the mean | |
| Standard deviation | the square root of the variance, in the same unit as the data | |
| Sample | a part of the data used to describe the whole |
The cells students fill in are left blank in this preview.
Two data sets can share a mean
The mean tells you where the middle of the data is. It says nothing about how far the values stray from it. That second fact is the spread.
The simplest measure of spread is the range: the highest value minus the lowest.
Worked example: same mean, different range
| Station | Hires on five days | Mean | Highest minus lowest |
|---|---|---|---|
| A | 238, 240, 242, 240, 240 | 1200 / 5 = 240 | 242 - 238 = 4 |
| B | 100, 380, 240, 150, 330 | 1200 / 5 = 240 | 380 - 100 = 280 |
The cells students fill in are left blank in this preview.
Quartiles ignore the extreme days
The range uses only two days, the highest and the lowest. One odd day can change it a lot.
A quartile cuts ordered data into quarters. The first quartile has a quarter of the values below it. The third has three quarters below it. The gap between them is the interquartile range. It is the spread of the middle half of the days.
Find the range and quartiles
docker exec jupyter python3 -c "import pandas as pd; h = pd.read_csv('hires.csv'); print(h['hires'].min(), h['hires'].max(), h['hires'].quantile(0.25), h['hires'].quantile(0.75))"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Variance is the mean of the squared gaps
A better spread uses every value. For each value, find its gap from the mean. Square each gap, so that a gap below the mean does not cancel a gap above it. Then take the mean of the squares. That is the variance.
The variance is in squared units, such as bikes squared. Its square root, the standard deviation, is back in bikes.
Worked example: variance by hand
| Day | Hires | Gap from mean 240 | Gap squared |
|---|---|---|---|
| 1 | 180 | -60 | 3600 |
| 2 | 210 | -30 | 900 |
| 3 | 240 | 0 | 0 |
| 4 | 260 | 20 | 400 |
| 5 | 310 | 70 | 4900 |
| Total | 1200 | 0 | 9800 |
| Result | Mean 240 | Variance 9800 / 5 = 1960 | Standard deviation 44.3 |
The cells students fill in are left blank in this preview.
Work out the variance in Python
# Five days of hires at one station.
days = [180, 210, 240, 260, 310]
total = 0
for one in days:
total = total + one
centre = total / len(days)
squares = 0
for one in days:
gap = one - centre
squares = squares + gap * gap
print("mean:", centre)
print("variance:", squares / len(days))
print("standard deviation:", round((squares / len(days)) ** 0.5, 1))
# Change 310 to 500 and run again.
# Which of the three numbers grows the most?
A sample divides by n minus 1
When your data is every value there is, divide the squared gaps by how many values you have, n. That gives the population variance.
When your data is only a sample of a bigger group, divide by n - 1 instead. A sample sits closer to its own mean than the whole group sits to the true mean, and the smaller divisor makes up for it.
Worked example: two divisors
| Divide the 9800 by | Variance | Standard deviation |
|---|---|---|
| n = 5, the whole group | 1960 | 44.3 |
| n - 1 = 4, a sample | 2450 | 49.5 |
The cells students fill in are left blank in this preview.
Compare pandas and NumPy
docker exec jupyter python3 -c "import numpy as np, pandas as pd; v = pd.read_csv('hires.csv')['hires'].head(5); print(round(v.std(), 1), round(np.std(v.to_numpy()), 1))"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
A common mistake
Warning
Many people think every library gives the same standard deviation. It does not. pandas divides by n - 1 and NumPy divides by n. Use the ddof setting to choose, and always know which one you are reading.
Going further
In your own notebook, find the standard deviation of temp_c, then of rain_mm. Which one varies more in its own unit?
Then find a pair of columns where the standard deviations are close but the units differ. Say why comparing them directly would mislead a reader.