summaryrefslogtreecommitdiff
path: root/numpy/lib
diff options
context:
space:
mode:
authorMatteo Raso <33975162+MatteoRaso@users.noreply.github.com>2022-12-08 07:01:59 -0500
committerGitHub <noreply@github.com>2022-12-08 13:01:59 +0100
commitb3c0960a54c81a26bd07912dda96db9e356b34d1 (patch)
tree2eca2dbef14e50ddc3340c20413c60e011c62ff2 /numpy/lib
parent6f9237e91ef26df62d40161458178f972db7ce26 (diff)
downloadnumpy-b3c0960a54c81a26bd07912dda96db9e356b34d1.tar.gz
BUG: Quantile function on complex number now throws an error (#22652) (#22703)
Since percentile is more or less identical to quantile, I also made it throw an error if it receives a complex input. I also made nanquantile and nanpercentile throw errors as well. * Made the changes recommended by seberg * Fixed a test for PR 22703 * Fixed tests for quantile * Shortened some more lines * Fixup more lines Co-authored-by: Sebastian Berg <sebastianb@nvidia.com>
Diffstat (limited to 'numpy/lib')
-rw-r--r--numpy/lib/function_base.py13
-rw-r--r--numpy/lib/nanfunctions.py7
-rw-r--r--numpy/lib/tests/test_function_base.py24
-rw-r--r--numpy/lib/tests/test_nanfunctions.py38
4 files changed, 67 insertions, 15 deletions
diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py
index 35a3b3543..9989e9759 100644
--- a/numpy/lib/function_base.py
+++ b/numpy/lib/function_base.py
@@ -3934,7 +3934,7 @@ def percentile(a,
Parameters
----------
- a : array_like
+ a : array_like of real numbers
Input array or object that can be converted to an array.
q : array_like of float
Percentile or sequence of percentiles to compute, which must be between
@@ -4198,6 +4198,11 @@ def percentile(a,
if interpolation is not None:
method = _check_interpolation_as_method(
method, interpolation, "percentile")
+
+ a = np.asanyarray(a)
+ if a.dtype.kind == "c":
+ raise TypeError("a must be an array of real numbers")
+
q = np.true_divide(q, 100)
q = asanyarray(q) # undo any decay that the ufunc performed (see gh-13105)
if not _quantile_is_valid(q):
@@ -4228,7 +4233,7 @@ def quantile(a,
Parameters
----------
- a : array_like
+ a : array_like of real numbers
Input array or object that can be converted to an array.
q : array_like of float
Quantile or sequence of quantiles to compute, which must be between
@@ -4455,6 +4460,10 @@ def quantile(a,
method = _check_interpolation_as_method(
method, interpolation, "quantile")
+ a = np.asanyarray(a)
+ if a.dtype.kind == "c":
+ raise TypeError("a must be an array of real numbers")
+
q = np.asanyarray(q)
if not _quantile_is_valid(q):
raise ValueError("Quantiles must be in the range [0, 1]")
diff --git a/numpy/lib/nanfunctions.py b/numpy/lib/nanfunctions.py
index ae2dfa165..786d2021e 100644
--- a/numpy/lib/nanfunctions.py
+++ b/numpy/lib/nanfunctions.py
@@ -1373,6 +1373,9 @@ def nanpercentile(
method, interpolation, "nanpercentile")
a = np.asanyarray(a)
+ if a.dtype.kind == "c":
+ raise TypeError("a must be an array of real numbers")
+
q = np.true_divide(q, 100.0)
# undo any decay that the ufunc performed (see gh-13105)
q = np.asanyarray(q)
@@ -1527,11 +1530,15 @@ def nanquantile(
The American Statistician, 50(4), pp. 361-365, 1996
"""
+
if interpolation is not None:
method = function_base._check_interpolation_as_method(
method, interpolation, "nanquantile")
a = np.asanyarray(a)
+ if a.dtype.kind == "c":
+ raise TypeError("a must be an array of real numbers")
+
q = np.asanyarray(q)
if not function_base._quantile_is_valid(q):
raise ValueError("Quantiles must be in the range [0, 1]")
diff --git a/numpy/lib/tests/test_function_base.py b/numpy/lib/tests/test_function_base.py
index 1bb4c4efa..e38a187d8 100644
--- a/numpy/lib/tests/test_function_base.py
+++ b/numpy/lib/tests/test_function_base.py
@@ -2973,6 +2973,14 @@ class TestPercentile:
o = np.ones((1,))
np.percentile(d, 5, None, o, False, 'linear')
+ def test_complex(self):
+ arr_c = np.array([0.5+3.0j, 2.1+0.5j, 1.6+2.3j], dtype='G')
+ assert_raises(TypeError, np.percentile, arr_c, 0.5)
+ arr_c = np.array([0.5+3.0j, 2.1+0.5j, 1.6+2.3j], dtype='D')
+ assert_raises(TypeError, np.percentile, arr_c, 0.5)
+ arr_c = np.array([0.5+3.0j, 2.1+0.5j, 1.6+2.3j], dtype='F')
+ assert_raises(TypeError, np.percentile, arr_c, 0.5)
+
def test_2D(self):
x = np.array([[1, 1, 1],
[1, 1, 1],
@@ -2981,7 +2989,7 @@ class TestPercentile:
[1, 1, 1]])
assert_array_equal(np.percentile(x, 50, axis=0), [1, 1, 1])
- @pytest.mark.parametrize("dtype", np.typecodes["AllFloat"])
+ @pytest.mark.parametrize("dtype", np.typecodes["Float"])
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)
@@ -2998,9 +3006,6 @@ class TestPercentile:
(np.float32, np.float32),
(np.float64, np.float64),
(np.longdouble, np.longdouble),
- (np.complex64, np.complex64),
- (np.complex128, np.complex128),
- (np.clongdouble, np.clongdouble),
(np.dtype("O"), np.float64)]
@pytest.mark.parametrize(["input_dtype", "expected_dtype"], H_F_TYPE_CODES)
@@ -3040,7 +3045,7 @@ class TestPercentile:
np.testing.assert_equal(np.asarray(actual).dtype,
np.dtype(expected_dtype))
- TYPE_CODES = np.typecodes["AllInteger"] + np.typecodes["AllFloat"] + "O"
+ TYPE_CODES = np.typecodes["AllInteger"] + np.typecodes["Float"] + "O"
@pytest.mark.parametrize("dtype", TYPE_CODES)
def test_lower_higher(self, dtype):
@@ -3517,6 +3522,15 @@ class TestQuantile:
x = np.arange(8)
assert_equal(np.quantile(x, Fraction(1, 2)), Fraction(7, 2))
+ def test_complex(self):
+ #See gh-22652
+ arr_c = np.array([0.5+3.0j, 2.1+0.5j, 1.6+2.3j], dtype='G')
+ assert_raises(TypeError, np.quantile, arr_c, 0.5)
+ arr_c = np.array([0.5+3.0j, 2.1+0.5j, 1.6+2.3j], dtype='D')
+ assert_raises(TypeError, np.quantile, arr_c, 0.5)
+ arr_c = np.array([0.5+3.0j, 2.1+0.5j, 1.6+2.3j], dtype='F')
+ assert_raises(TypeError, np.quantile, arr_c, 0.5)
+
def test_no_p_overwrite(self):
# this is worth retesting, because quantile does not make a copy
p0 = np.array([0, 0.75, 0.25, 0.5, 1.0])
diff --git a/numpy/lib/tests/test_nanfunctions.py b/numpy/lib/tests/test_nanfunctions.py
index 64464edcc..45cacb792 100644
--- a/numpy/lib/tests/test_nanfunctions.py
+++ b/numpy/lib/tests/test_nanfunctions.py
@@ -404,14 +404,20 @@ class TestNanFunctions_NumberTypes:
)
def test_nanfunc_q(self, mat, dtype, nanfunc, func):
mat = mat.astype(dtype)
- tgt = func(mat, q=1)
- out = nanfunc(mat, q=1)
+ if mat.dtype.kind == "c":
+ assert_raises(TypeError, func, mat, q=1)
+ assert_raises(TypeError, nanfunc, mat, q=1)
- assert_almost_equal(out, tgt)
- if dtype == "O":
- assert type(out) is type(tgt)
else:
- assert out.dtype == tgt.dtype
+ tgt = func(mat, q=1)
+ out = nanfunc(mat, q=1)
+
+ assert_almost_equal(out, tgt)
+
+ if dtype == "O":
+ assert type(out) is type(tgt)
+ else:
+ assert out.dtype == tgt.dtype
@pytest.mark.parametrize(
"nanfunc,func",
@@ -1058,6 +1064,14 @@ class TestNanFunctions_Percentile:
assert_almost_equal(res, resout)
assert_almost_equal(res, tgt)
+ def test_complex(self):
+ arr_c = np.array([0.5+3.0j, 2.1+0.5j, 1.6+2.3j], dtype='G')
+ assert_raises(TypeError, np.nanpercentile, arr_c, 0.5)
+ arr_c = np.array([0.5+3.0j, 2.1+0.5j, 1.6+2.3j], dtype='D')
+ assert_raises(TypeError, np.nanpercentile, arr_c, 0.5)
+ arr_c = np.array([0.5+3.0j, 2.1+0.5j, 1.6+2.3j], dtype='F')
+ assert_raises(TypeError, np.nanpercentile, arr_c, 0.5)
+
def test_result_values(self):
tgt = [np.percentile(d, 28) for d in _rdat]
res = np.nanpercentile(_ndat, 28, axis=1)
@@ -1068,7 +1082,7 @@ class TestNanFunctions_Percentile:
assert_almost_equal(res, tgt)
@pytest.mark.parametrize("axis", [None, 0, 1])
- @pytest.mark.parametrize("dtype", np.typecodes["AllFloat"])
+ @pytest.mark.parametrize("dtype", np.typecodes["Float"])
@pytest.mark.parametrize("array", [
np.array(np.nan),
np.full((3, 3), np.nan),
@@ -1162,6 +1176,14 @@ class TestNanFunctions_Quantile:
assert_equal(np.nanquantile(x, 1), 3.5)
assert_equal(np.nanquantile(x, 0.5), 1.75)
+ def test_complex(self):
+ arr_c = np.array([0.5+3.0j, 2.1+0.5j, 1.6+2.3j], dtype='G')
+ assert_raises(TypeError, np.nanquantile, arr_c, 0.5)
+ arr_c = np.array([0.5+3.0j, 2.1+0.5j, 1.6+2.3j], dtype='D')
+ assert_raises(TypeError, np.nanquantile, arr_c, 0.5)
+ arr_c = np.array([0.5+3.0j, 2.1+0.5j, 1.6+2.3j], dtype='F')
+ assert_raises(TypeError, np.nanquantile, arr_c, 0.5)
+
def test_no_p_overwrite(self):
# this is worth retesting, because quantile does not make a copy
p0 = np.array([0, 0.75, 0.25, 0.5, 1.0])
@@ -1175,7 +1197,7 @@ class TestNanFunctions_Quantile:
assert_array_equal(p, p0)
@pytest.mark.parametrize("axis", [None, 0, 1])
- @pytest.mark.parametrize("dtype", np.typecodes["AllFloat"])
+ @pytest.mark.parametrize("dtype", np.typecodes["Float"])
@pytest.mark.parametrize("array", [
np.array(np.nan),
np.full((3, 3), np.nan),