Skip to content

Commit 85f3dda

Browse files
committed
BUG: quantile discrete methods ended up using -1 as index sometimes
Also, the closest-observation did not correctly support multiple quantiles calculated at the same time (broadcasting error).
1 parent 3993408 commit 85f3dda

File tree

2 files changed

+22
-9
lines changed

2 files changed

+22
-9
lines changed

numpy/lib/function_base.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4487,19 +4487,22 @@ def _lerp(a, b, t, out=None):
44874487

44884488
def _get_gamma_mask(shape, default_value, conditioned_value, where):
44894489
out = np.full(shape, default_value)
4490-
out[where] = conditioned_value
4490+
np.copyto(out, conditioned_value, where=where, casting="unsafe")
44914491
return out
44924492

44934493

44944494
def _discret_interpolation_to_boundaries(index, gamma_condition_fun):
44954495
previous = np.floor(index)
44964496
next = previous + 1
44974497
gamma = index - previous
4498-
return _get_gamma_mask(shape=index.shape,
4499-
default_value=next,
4500-
conditioned_value=previous,
4501-
where=gamma_condition_fun(gamma, index)
4502-
).astype(np.intp)
4498+
res = _get_gamma_mask(shape=index.shape,
4499+
default_value=next,
4500+
conditioned_value=previous,
4501+
where=gamma_condition_fun(gamma, index)
4502+
).astype(np.intp)
4503+
# Some methods can lead to out-of-bound integers, clip them:
4504+
res[res < 0] = 0
4505+
return res
45034506

45044507

45054508
def _closest_observation(n, quantiles):

numpy/lib/tests/test_function_base.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3426,12 +3426,22 @@ def test_quantile_preserve_int_type(self, dtype):
34263426
method="nearest")
34273427
assert res.dtype == dtype
34283428

3429-
def test_quantile_monotonic(self):
3429+
@pytest.mark.parametrize("method",
3430+
['inverted_cdf', 'averaged_inverted_cdf', 'closest_observation',
3431+
'interpolated_inverted_cdf', 'hazen', 'weibull', 'linear',
3432+
'median_unbiased', 'normal_unbiased',
3433+
'nearest', 'lower', 'higher', 'midpoint'])
3434+
def test_quantile_monotonic(self, method):
34303435
# GH 14685
34313436
# test that the return value of quantile is monotonic if p0 is ordered
3432-
p0 = np.arange(0, 1, 0.01)
3437+
# Also tests that the boundary values are not mishandled.
3438+
p0 = np.linspace(0, 1, 101)
34333439
quantile = np.quantile(np.array([0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 1, 1, 9, 9, 9,
3434-
8, 8, 7]) * 0.1, p0)
3440+
8, 8, 7]) * 0.1, p0, method=method)
3441+
assert_equal(np.sort(quantile), quantile)
3442+
3443+
# Also test one where the number of data points is clearly divisible:
3444+
quantile = np.quantile([0., 1., 2., 3.], p0, method=method)
34353445
assert_equal(np.sort(quantile), quantile)
34363446

34373447
@hypothesis.given(

0 commit comments

Comments
 (0)