statistics: quantiles() Can Extrapolate Past the Data's Range (tested)
statistics.quantiles() cuts a dataset into equal-probability intervals, and it's natural to assume every returned cut point falls somewhere between the data's minimum and maximum. We measured what happens when n (the number of intervals) is large relative to the number of data points, and the cut points aren't clamped to the observed range at all.
1. With n=100 on 10 data points, some quantile values fall outside the data entirely
import statistics as st
data = list(range(1, 11))
qs = st.quantiles(data, n=100)
print("data range:", min(data), "-", max(data))
print("quantile range:", min(qs), "-", max(qs))
data range: 1 - 10
quantile range: 0.11 - 10.89
Measured: the 10 data points range from 1 to 10, but the 99 returned quantile cut points range from 0.11 to 10.89 -- 18 of the 99 values fall outside [1, 10] entirely, both below the minimum and above the maximum observed value.
2. This is linear extrapolation, not an error or a clamp
import statistics as st
data = list(range(1, 11))
qs = st.quantiles(data, n=100)
outside = [q for q in qs if q < min(data) or q > max(data)]
print(len(outside), "of", len(qs), "values outside the data range")
print(outside[:3], "...", outside[-3:])
18 of 99 values outside the data range
[0.11, 0.22, 0.33] ... [10.67, 10.78, 10.89]
Measured: the default exclusive method interpolates linearly between ranks that extend slightly past the first and last data points when n is large relative to the sample size -- it never raises, never clamps to min(data)/max(data), and produces no warning that any value is outside what was actually observed.
3. A smaller n relative to the data stays safely inside the range
import statistics as st
data = list(range(1, 11))
print(st.quantiles(data, n=3))
print(st.quantiles(data, n=4))
[3.6666666666666665, 7.333333333333333]
[3.25, 5.5, 7.75]
Measured: with a modest n (quartiles, terciles), every returned value stays comfortably inside the data's actual range -- this is almost certainly why the extrapolation goes unnoticed in typical use, since most code calls quantiles() with a small fixed n like 4 or 10. The problem only shows up once n is pushed high relative to a small sample (a common pattern when building a percentile table or a fine-grained histogram from limited data). If downstream code treats a quantile result as "a value this data could plausibly contain" (e.g. clamping a measurement into a percentile bucket, or asserting a result is within the sample's bounds), it will silently fail once a large n is used on a small dataset. Clamp the output to min(data)/max(data) explicitly if values outside the observed range aren't valid for your use case, or keep n well below the data's point count.
Frequently asked questions
Can statistics.quantiles() return values below the minimum or above the maximum of the input data?
Yes -- we measured statistics.quantiles(range(1, 11), n=100) returning values from 0.11 to 10.89, even though the input data only ranges from 1 to 10. This happens when n is large relative to the number of data points.
Why does statistics.quantiles() extrapolate beyond the data's range?
Its default interpolation method computes cut points by linear interpolation between ranks, and with a high n relative to a small sample, some of those computed ranks fall just past the first or last data point -- the function doesn't clamp the result to the observed min/max.
How do I keep statistics.quantiles() results within the data's actual range?
Clamp each returned value to min(data)/max(data) explicitly after calling quantiles(), or keep n well below the number of data points -- we confirmed modest values like n=3 or n=4 stay safely inside the observed range for the same data.
Does a small n avoid the out-of-range problem in statistics.quantiles()?
Yes -- we measured quantiles(range(1,11), n=4) returning [3.25, 5.5, 7.75], all comfortably inside the data's 1-10 range. The extrapolation only becomes visible once n is pushed high relative to the sample size.
Written with AI assistance. Measured on 2026-10-04 with Python 3.13.5's built-in statistics module: called quantiles() with n much larger than the number of data points, and compared the returned values to the data's actual min and max. PlainHeaders is our extension; Python's statistics module is built in.