Beginner: data foundations · Statistics made simple · topic 8 of 62 · 30 min
Percentiles, quartiles and outliers
Explanation
Why positions matter
The mean and SD summarise the whole column, but people often ask "where do I stand?". If you scored 72 in an exam, that alone says little. If 90% of students scored at or below 72, you did very well. Positions in sorted data, called percentiles, answer that kind of question, and they are not thrown off by outliers.
Percentiles and percentile rank
The p-th percentile is a value that about p percent of the data is at or below. The 50th percentile is the median. The other direction is the percentile rank of a value: what percent of the data is at or below it. JEE Main, for example, reports an NTA percentile, which is roughly the percentage of candidates in your session who scored equal to or less than you. So a percentile is about your position, not your marks.
marks = [35, 42, 50, 55, 61, 64, 70, 72, 81, 95]
x = 72
at_or_below = sum(1 for m in marks if m <= x)
print(100 * at_or_below / len(marks)) # 80.0Quartiles and the IQR
Quartiles cut sorted data into four equal parts. Q1, the first quartile, is the 25th percentile; Q2 is the median; Q3 is the 75th percentile. The interquartile range, IQR = Q3 − Q1, is the spread of the middle 50% of the data. Because it ignores the top and bottom quarters, one extreme value cannot blow it up, unlike the range and the SD.
import statistics
times = [22, 25, 27, 28, 30, 31, 33, 35, 36, 40, 95] # delivery minutes, sorted
q1, q2, q3 = statistics.quantiles(times, n=4)
print(q1, q2, q3) # 27.0 31.0 36.0
print(q3 - q1) # 9.0The 1.5 × IQR rule for outliers
A common rule, from the statistician John Tukey, flags a value as a possible outlier if it is below Q1 − 1.5 × IQR or above Q3 + 1.5 × IQR. These two limits are called the fences. Here the fences are 27 − 13.5 = 13.5 and 36 + 13.5 = 49.5, so the 95-minute delivery is flagged.
iqr = q3 - q1
low, high = q1 - 1.5 * iqr, q3 + 1.5 * iqr
print(low, high) # 13.5 49.5
print([t for t in times if t < low or t > high]) # [95]Box plots
A box plot (box-and-whisker plot) draws these numbers. The box runs from Q1 to Q3 with a line at the median. The whiskers reach out to the furthest values that are still inside the fences, and points beyond the fences are drawn one by one as outliers. Box plots make it easy to compare spread across groups, such as delivery times per city.
22 27 31 36 40 95
|----------[======|======]--------| o
whisker Q1 median Q3 whisker outlierimport matplotlib.pyplot as plt
plt.boxplot(times) # whiskers use 1.5 × IQR by default
plt.ylabel("Delivery time (minutes)")
plt.show()Careful: tools disagree on quartiles
When a quartile falls between two data values, tools use different rules to pick a number in between. None is "wrong"; they are different conventions. On the numbers 1 to 10 you get three different Q1 values:
import statistics
data = list(range(1, 11))
print(statistics.quantiles(data, n=4)) # [2.75, 5.5, 8.25]
print(statistics.quantiles(data, n=4, method="inclusive")) # [3.25, 5.5, 7.75]A third method, often taught in school, splits the sorted data into a lower half and an upper half (leaving out the middle value when the count is odd) and takes the median of each half. For 1 to 10 that gives Q1 = 3 and Q3 = 8. With large datasets the methods agree closely; with small ones, always say which method you used.
Common mistakes
- Confusing percentage and percentile. 90 percent means 90 marks out of 100; the 90th percentile means you did at least as well as 90% of people.
- Comparing quartiles from two tools that use different methods. Fix: use one tool, or set the method explicitly.
- Deleting every flagged outlier. Fix: investigate first; keep real extreme values and document every removal.
- Using the 1.5 × IQR rule on tiny samples of 4 or 5 values, where quartiles are unstable. Fix: look at the actual values instead.
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
Percentiles, quartiles and outliers · 1/7
In this lesson you will describe where a value stands, and find outliers, using percentiles and quartiles.
Prefer a video by a teacher? Find free videos on “quartiles interquartile range outliers box plot explained” on YouTube ↗
In real life: Spotting suspicious transactions
Banks and payment apps watch for unusual transactions. One simple first check is to compare each new payment with that customer's usual range: if a person usually spends ₹200–₹2,000 per UPI payment, a sudden ₹90,000 payment sits far above their Q3 + 1.5 × IQR fence and can be sent for an extra check. Real fraud systems use many more signals, but percentiles and fences are a common, easy-to-explain starting point. The numbers below are made up.
import statistics
payments = [250, 400, 180, 900, 1200, 650, 300, 2000, 750, 90000]
q1, _, q3 = statistics.quantiles(payments, n=4)
fence = q3 + 1.5 * (q3 - q1)
print(q1, q3, fence)
print([p for p in payments if p > fence])Practice (0/3 done)
Write iqr_outliers(values, q1, q3) that uses the given quartiles to compute IQR = q3 − q1 and the fences q1 − 1.5 × IQR and q3 + 1.5 × IQR. Return the values strictly below the low fence or strictly above the high fence, in their original order. A value exactly on a fence is not an outlier.
Write percentile_rank(values, x) that returns the percent of values that are less than or equal to x, rounded to 1 decimal place. Return None for an empty list.
Write quartiles_by_halves(values) using the "median of halves" method: sort the values; if the count is odd, leave out the middle value; Q1 is the median of the lower half and Q3 is the median of the upper half. Return the tuple (q1, q3). The list always has at least 2 values.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- The normal distribution and z-scoresStatistics made simple · same module
- Monitoring and observability: metrics, logs and tracesDevOps: Git, Docker, Kubernetes and CI/CD · Monitoring and logging
- Ranking: ROW_NUMBER, RANK, DENSE_RANK and NTILESQL and Databases · Window functions
- More array powerFrontend Web Development · JavaScript in depth
- Interview questions: ownership, borrowing and lifetimesRust Programming · Rust careers and interviews
- Scaling and transforming numbersClustering, dimensionality reduction and feature engineering
Questions people ask about this
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.
A student is at the 85th percentile in an exam. What does that mean?
Answer: She did at least as well as about 85% of the students
A percentile is about position among people, not about marks.
Q1 = 40 and Q3 = 60. Which value is flagged by the 1.5 × IQR rule?
Answer: 95
IQR = 20, so the fences are 40 − 30 = 10 and 60 + 30 = 90. Only 95 lies beyond a fence; 15, 35 and 85 are inside.
Why is the IQR often preferred to the range for skewed data?
Answer: It uses only the middle 50% of values, so extreme values do not distort it
The IQR ignores the top and bottom quarters, where outliers live.
statistics.quantiles(range(1, 11), n=4) gives Q1 = 2.75, but np.percentile gives 3.25. Why?
Answer: The tools use different, equally valid interpolation methods
Python's default is the "exclusive" method; NumPy's default is linear interpolation, which matches "inclusive".
A box plot shows a dot far above the top whisker. What should you do first?
Answer: Check that record to see if it is an error or a real extreme value
Outliers can be mistakes or real events. Investigate, then decide and document.
In right-skewed data such as house prices, how do the mean and median usually compare?Related
Answer: The mean is bigger
The long tail of very expensive houses pulls the mean above the median.
90 requests take 100 ms and 10 take 3,000 ms. What is the p95 latency (nearest rank)?Related
Answer: 3,000 ms
Rank ceil(95 x 100 / 100) = 95. The 95th sorted value is one of the 3,000 ms requests.
Salaries in order are 300, 200, 200, 100. What does RANK() OVER (ORDER BY salary DESC) give?Related
Answer: 1, 2, 2, 4
RANK gives ties the same number and then skips, so the next rank is 4.
In an exam with mean 60 and SD 10, what is the z-score of 45?Related
Answer: -1.5
z = (45 − 60) / 10 = −1.5: one and a half SDs below the mean.
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
- 2 more topics in “Statistics made simple” before its exam: The normal distribution and z-scores, Correlation: how two things move together.
- Module 2 exam: Statistics made simple · 14 questions · 25 min, without help. 5 topics of this module still to finish first.
- Then the next module, Probability and inference. 62 topics left in the course before the final exam.