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.