diff options
Diffstat (limited to 'numpy/lib/tests/test_function_base.py')
-rw-r--r-- | numpy/lib/tests/test_function_base.py | 144 |
1 files changed, 108 insertions, 36 deletions
diff --git a/numpy/lib/tests/test_function_base.py b/numpy/lib/tests/test_function_base.py index c7dfe5673..d5fa012f1 100644 --- a/numpy/lib/tests/test_function_base.py +++ b/numpy/lib/tests/test_function_base.py @@ -2903,36 +2903,95 @@ class TestPercentile: [1, 1, 1]]) assert_array_equal(np.percentile(x, 50, axis=0), [1, 1, 1]) - def test_linear(self): - - # Test defaults - assert_equal(np.percentile(range(10), 50), 4.5) - - # explicitly specify interpolation_method 'linear' (the default) - assert_equal(np.percentile(range(10), 50, - interpolation='linear'), 4.5) + @pytest.mark.parametrize("dtype", np.typecodes["AllFloat"]) + def test_linear_nan_1D(self, dtype): + # METHOD 1 of H&F + arr = np.asarray([15.0, np.NAN, 35.0, 40.0, 50.0], dtype=dtype) + res = np.percentile( + arr, + 40.0, + interpolation="linear") + np.testing.assert_equal(res, np.NAN) + np.testing.assert_equal(res.dtype, arr.dtype) + + H_F_TYPE_CODES = [(int_type, np.float64) + for int_type in np.typecodes["AllInteger"] + ] + [(np.float16, np.float64), + (np.float32, np.float64), + (np.float64, np.float64), + (np.longdouble, np.longdouble), + (np.complex64, np.complex128), + (np.complex128, np.complex128), + (np.clongdouble, np.clongdouble), + (np.dtype("O"), np.float64)] + + @pytest.mark.parametrize(["input_dtype", "expected_dtype"], H_F_TYPE_CODES) + @pytest.mark.parametrize(["interpolation", "expected"], + [("inverted_cdf", 20), + ("averaged_inverted_cdf", 27.5), + ("closest_observation", 20), + ("interpolated_inverted_cdf", 20), + ("hazen", 27.5), + ("weibull", 26), + ("linear", 29), + ("median_unbiased", 27), + ("normal_unbiased", 27.125), + ]) + def test_linear_interpolation(self, + interpolation, + expected, + input_dtype, + expected_dtype): + arr = np.asarray([15.0, 20.0, 35.0, 40.0, 50.0], dtype=input_dtype) + actual = np.percentile(arr, 40.0, interpolation=interpolation) + + np.testing.assert_almost_equal(actual, expected, 14) + + if interpolation in ["inverted_cdf", "closest_observation"]: + if input_dtype == "O": + np.testing.assert_equal(np.asarray(actual).dtype, np.float64) + else: + np.testing.assert_equal(np.asarray(actual).dtype, + np.dtype(input_dtype)) + else: + np.testing.assert_equal(np.asarray(actual).dtype, + np.dtype(expected_dtype)) - def test_lower_higher(self): + TYPE_CODES = np.typecodes["AllInteger"] + np.typecodes["AllFloat"] + "O" - # interpolation_method 'lower'/'higher' - assert_equal(np.percentile(range(10), 50, + @pytest.mark.parametrize("dtype", TYPE_CODES) + def test_lower_higher(self, dtype): + assert_equal(np.percentile(np.arange(10, dtype=dtype), 50, interpolation='lower'), 4) - assert_equal(np.percentile(range(10), 50, + assert_equal(np.percentile(np.arange(10, dtype=dtype), 50, interpolation='higher'), 5) - def test_midpoint(self): - assert_equal(np.percentile(range(10), 51, + @pytest.mark.parametrize("dtype", TYPE_CODES) + def test_midpoint(self, dtype): + assert_equal(np.percentile(np.arange(10, dtype=dtype), 51, interpolation='midpoint'), 4.5) - assert_equal(np.percentile(range(11), 51, + assert_equal(np.percentile(np.arange(9, dtype=dtype) + 1, 50, + interpolation='midpoint'), 5) + assert_equal(np.percentile(np.arange(11, dtype=dtype), 51, interpolation='midpoint'), 5.5) - assert_equal(np.percentile(range(11), 50, + assert_equal(np.percentile(np.arange(11, dtype=dtype), 50, interpolation='midpoint'), 5) - def test_nearest(self): - assert_equal(np.percentile(range(10), 51, + @pytest.mark.parametrize("dtype", TYPE_CODES) + def test_nearest(self, dtype): + assert_equal(np.percentile(np.arange(10, dtype=dtype), 51, interpolation='nearest'), 5) - assert_equal(np.percentile(range(10), 49, - interpolation='nearest'), 4) + assert_equal(np.percentile(np.arange(10, dtype=dtype), 49, + interpolation='nearest'), 4) + + def test_linear_interpolation_extrapolation(self): + arr = np.random.rand(5) + + actual = np.percentile(arr, 100) + np.testing.assert_equal(actual, arr.max()) + + actual = np.percentile(arr, 0) + np.testing.assert_equal(actual, arr.min()) def test_sequence(self): x = np.arange(8) * 0.5 @@ -3038,18 +3097,18 @@ class TestPercentile: y = np.zeros((3,)) p = (1, 2, 3) np.percentile(x, p, out=y) - assert_equal(y, np.percentile(x, p)) + assert_equal(np.percentile(x, p), y) x = np.array([[1, 2, 3], [4, 5, 6]]) y = np.zeros((3, 3)) np.percentile(x, p, axis=0, out=y) - assert_equal(y, np.percentile(x, p, axis=0)) + assert_equal(np.percentile(x, p, axis=0), y) y = np.zeros((3, 2)) np.percentile(x, p, axis=1, out=y) - assert_equal(y, np.percentile(x, p, axis=1)) + assert_equal(np.percentile(x, p, axis=1), y) x = np.arange(12).reshape(3, 4) # q.dim > 1, float @@ -3293,6 +3352,7 @@ class TestPercentile: with pytest.raises(ValueError, match="Percentiles must be in"): np.percentile([1, 2, 3, 4.0], q) + class TestQuantile: # most of this is already tested by TestPercentile @@ -3302,6 +3362,7 @@ class TestQuantile: assert_equal(np.quantile(x, 1), 3.5) assert_equal(np.quantile(x, 0.5), 1.75) + @pytest.mark.xfail(reason="See gh-19154") def test_correct_quantile_value(self): a = np.array([True]) tf_quant = np.quantile(True, False) @@ -3310,12 +3371,11 @@ class TestQuantile: a = np.array([False, True, True]) quant_res = np.quantile(a, a) assert_array_equal(quant_res, a) - assert_equal(a.dtype, quant_res.dtype) + assert_equal(quant_res.dtype, a.dtype) def test_fraction(self): # fractional input, integral quantile x = [Fraction(i, 2) for i in range(8)] - q = np.quantile(x, 0) assert_equal(q, 0) assert_equal(type(q), Fraction) @@ -3352,6 +3412,12 @@ class TestQuantile: np.quantile(np.arange(100.), p, interpolation="midpoint") assert_array_equal(p, p0) + @pytest.mark.parametrize("dtype", np.typecodes["AllInteger"]) + def test_quantile_preserve_int_type(self, dtype): + res = np.quantile(np.array([1, 2], dtype=dtype), [0.5], + interpolation="nearest") + assert res.dtype == dtype + def test_quantile_monotonic(self): # GH 14685 # test that the return value of quantile is monotonic if p0 is ordered @@ -3370,6 +3436,12 @@ class TestQuantile: quantile = np.quantile(arr, p0) assert_equal(np.sort(quantile), quantile) + def test_quantile_scalar_nan(self): + a = np.array([[10., 7., 4.], [3., 2., 1.]]) + a[0][1] = np.nan + actual = np.quantile(a, 0.5) + assert np.isscalar(actual) + assert_equal(np.quantile(a, 0.5), np.nan) class TestLerp: @hypothesis.given(t0=st.floats(allow_nan=False, allow_infinity=False, @@ -3380,9 +3452,9 @@ class TestLerp: min_value=-1e300, max_value=1e300), b = st.floats(allow_nan=False, allow_infinity=False, min_value=-1e300, max_value=1e300)) - def test_lerp_monotonic(self, t0, t1, a, b): - l0 = np.lib.function_base._lerp(a, b, t0) - l1 = np.lib.function_base._lerp(a, b, t1) + def test_linear_interpolation_formula_monotonic(self, t0, t1, a, b): + l0 = nfb._lerp(a, b, t0) + l1 = nfb._lerp(a, b, t1) if t0 == t1 or a == b: assert l0 == l1 # uninteresting elif (t0 < t1) == (a < b): @@ -3396,11 +3468,11 @@ class TestLerp: min_value=-1e300, max_value=1e300), b=st.floats(allow_nan=False, allow_infinity=False, min_value=-1e300, max_value=1e300)) - def test_lerp_bounded(self, t, a, b): + def test_linear_interpolation_formula_bounded(self, t, a, b): if a <= b: - assert a <= np.lib.function_base._lerp(a, b, t) <= b + assert a <= nfb._lerp(a, b, t) <= b else: - assert b <= np.lib.function_base._lerp(a, b, t) <= a + assert b <= nfb._lerp(a, b, t) <= a @hypothesis.given(t=st.floats(allow_nan=False, allow_infinity=False, min_value=0, max_value=1), @@ -3408,17 +3480,17 @@ class TestLerp: min_value=-1e300, max_value=1e300), b=st.floats(allow_nan=False, allow_infinity=False, min_value=-1e300, max_value=1e300)) - def test_lerp_symmetric(self, t, a, b): + def test_linear_interpolation_formula_symmetric(self, t, a, b): # double subtraction is needed to remove the extra precision of t < 0.5 - left = np.lib.function_base._lerp(a, b, 1 - (1 - t)) - right = np.lib.function_base._lerp(b, a, 1 - t) + left = nfb._lerp(a, b, 1 - (1 - t)) + right = nfb._lerp(b, a, 1 - t) assert left == right - def test_lerp_0d_inputs(self): + def test_linear_interpolation_formula_0d_inputs(self): a = np.array(2) b = np.array(5) t = np.array(0.2) - assert np.lib.function_base._lerp(a, b, t) == 2.6 + assert nfb._lerp(a, b, t) == 2.6 class TestMedian: |