Skip to content

Commit a0d86e2

Browse files
authored
Merge pull request numpy#20331 from bzah/fix/quantile-default-lerp-method
MAINT: Update quantile default lerp method
2 parents e1239e7 + 53e3df3 commit a0d86e2

File tree

2 files changed

+15
-5
lines changed

2 files changed

+15
-5
lines changed

numpy/lib/function_base.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
# fix_gamma : Callable
6868
# A function used for discret methods to force the index to a specific value.
6969
_QuantileInterpolation = dict(
70-
# --- HYNDMAN and FAN methods
70+
# --- HYNDMAN AND FAN METHODS
7171
# Discrete methods
7272
inverted_cdf=dict(
7373
get_virtual_index=lambda n, quantiles: _inverted_cdf(n, quantiles),
@@ -102,10 +102,12 @@
102102
_compute_virtual_index(n, quantiles, 0, 0),
103103
fix_gamma=lambda gamma, _: gamma,
104104
),
105-
# Default value
105+
# Default method.
106+
# To avoid some rounding issues, `(n-1) * quantiles` is preferred to
107+
# `_compute_virtual_index(n, quantiles, 1, 1)`.
108+
# They are mathematically equivalent.
106109
linear=dict(
107-
get_virtual_index=lambda n, quantiles:
108-
_compute_virtual_index(n, quantiles, 1, 1),
110+
get_virtual_index=lambda n, quantiles: (n - 1) * quantiles,
109111
fix_gamma=lambda gamma, _: gamma,
110112
),
111113
median_unbiased=dict(
@@ -118,7 +120,7 @@
118120
_compute_virtual_index(n, quantiles, 3 / 8.0, 3 / 8.0),
119121
fix_gamma=lambda gamma, _: gamma,
120122
),
121-
# --- OTHER METHODS fixme add deprecated ?
123+
# --- OTHER METHODS
122124
lower=dict(
123125
get_virtual_index=lambda n, quantiles: np.floor(
124126
(n - 1) * quantiles).astype(np.intp),

numpy/lib/tests/test_function_base.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3356,6 +3356,14 @@ def test_nan_q(self):
33563356
class TestQuantile:
33573357
# most of this is already tested by TestPercentile
33583358

3359+
def test_max_ulp(self):
3360+
x = [0.0, 0.2, 0.4]
3361+
a = np.quantile(x, 0.45)
3362+
# The default linear method would result in 0 + 0.2 * (0.45/2) = 0.18.
3363+
# 0.18 is not exactly representable and the formula leads to a 1 ULP
3364+
# different result. Ensure it is this exact within 1 ULP, see gh-20331.
3365+
np.testing.assert_array_max_ulp(a, 0.18, maxulp=1)
3366+
33593367
def test_basic(self):
33603368
x = np.arange(8) * 0.5
33613369
assert_equal(np.quantile(x, 0), 0.)

0 commit comments

Comments
 (0)