summaryrefslogtreecommitdiff
path: root/numpy/ma/tests
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/ma/tests')
-rw-r--r--numpy/ma/tests/test_core.py162
-rw-r--r--numpy/ma/tests/test_extras.py74
-rw-r--r--numpy/ma/tests/test_old_ma.py8
-rw-r--r--numpy/ma/tests/test_regression.py6
-rw-r--r--numpy/ma/tests/test_subclassing.py10
5 files changed, 249 insertions, 11 deletions
diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py
index 6196dcfab..6ab1d7e4f 100644
--- a/numpy/ma/tests/test_core.py
+++ b/numpy/ma/tests/test_core.py
@@ -8,6 +8,7 @@ __author__ = "Pierre GF Gerard-Marchant"
import sys
import warnings
+import copy
import operator
import itertools
import textwrap
@@ -21,8 +22,9 @@ import numpy.ma.core
import numpy.core.fromnumeric as fromnumeric
import numpy.core.umath as umath
from numpy.testing import (
- assert_raises, assert_warns, suppress_warnings
+ assert_raises, assert_warns, suppress_warnings, IS_WASM
)
+from numpy.testing._private.utils import requires_memory
from numpy import ndarray
from numpy.compat import asbytes
from numpy.ma.testutils import (
@@ -214,6 +216,8 @@ class TestMaskedArray:
assert_(np.may_share_memory(x.mask, y.mask))
y = array([1, 2, 3], mask=x._mask, copy=True)
assert_(not np.may_share_memory(x.mask, y.mask))
+ x = array([1, 2, 3], mask=None)
+ assert_equal(x._mask, [False, False, False])
def test_masked_singleton_array_creation_warns(self):
# The first works, but should not (ideally), there may be no way
@@ -373,6 +377,24 @@ class TestMaskedArray:
assert_equal(s1, s2)
assert_(x1[1:1].shape == (0,))
+ def test_setitem_no_warning(self):
+ # Setitem shouldn't warn, because the assignment might be masked
+ # and warning for a masked assignment is weird (see gh-23000)
+ # (When the value is masked, otherwise a warning would be acceptable
+ # but is not given currently.)
+ x = np.ma.arange(60).reshape((6, 10))
+ index = (slice(1, 5, 2), [7, 5])
+ value = np.ma.masked_all((2, 2))
+ value._data[...] = np.inf # not a valid integer...
+ x[index] = value
+ # The masked scalar is special cased, but test anyway (it's NaN):
+ x[...] = np.ma.masked
+ # Finally, a large value that cannot be cast to the float32 `x`
+ x = np.ma.arange(3., dtype=np.float32)
+ value = np.ma.array([2e234, 1, 1], mask=[True, False, False])
+ x[...] = value
+ x[[0, 1, 2]] = value
+
@suppress_copy_mask_on_assignment
def test_copy(self):
# Tests of some subtle points of copying and sizing.
@@ -1332,16 +1354,16 @@ class TestMaskedArrayArithmetic:
assert_equal(np.sum(x, axis=0), sum(x, axis=0))
assert_equal(np.sum(filled(xm, 0), axis=0), sum(xm, axis=0))
assert_equal(np.sum(x, 0), sum(x, 0))
- assert_equal(np.product(x, axis=0), product(x, axis=0))
- assert_equal(np.product(x, 0), product(x, 0))
- assert_equal(np.product(filled(xm, 1), axis=0), product(xm, axis=0))
+ assert_equal(np.prod(x, axis=0), product(x, axis=0))
+ assert_equal(np.prod(x, 0), product(x, 0))
+ assert_equal(np.prod(filled(xm, 1), axis=0), product(xm, axis=0))
s = (3, 4)
x.shape = y.shape = xm.shape = ym.shape = s
if len(s) > 1:
assert_equal(np.concatenate((x, y), 1), concatenate((xm, ym), 1))
assert_equal(np.add.reduce(x, 1), add.reduce(x, 1))
assert_equal(np.sum(x, 1), sum(x, 1))
- assert_equal(np.product(x, 1), product(x, 1))
+ assert_equal(np.prod(x, 1), product(x, 1))
def test_binops_d2D(self):
# Test binary operations on 2D data
@@ -3407,6 +3429,24 @@ class TestMaskedArrayMethods:
assert_equal(a.ravel(order='C'), [1, 2, 3, 4])
assert_equal(a.ravel(order='F'), [1, 3, 2, 4])
+ @pytest.mark.parametrize("order", "AKCF")
+ @pytest.mark.parametrize("data_order", "CF")
+ def test_ravel_order(self, order, data_order):
+ # Ravelling must ravel mask and data in the same order always to avoid
+ # misaligning the two in the ravel result.
+ arr = np.ones((5, 10), order=data_order)
+ arr[0, :] = 0
+ mask = np.ones((10, 5), dtype=bool, order=data_order).T
+ mask[0, :] = False
+ x = array(arr, mask=mask)
+ assert x._data.flags.fnc != x._mask.flags.fnc
+ assert (x.filled(0) == 0).all()
+ raveled = x.ravel(order)
+ assert (raveled.filled(0) == 0).all()
+
+ # NOTE: Can be wrong if arr order is neither C nor F and `order="K"`
+ assert_array_equal(arr.ravel(order), x.ravel(order)._data)
+
def test_reshape(self):
# Tests reshape
x = arange(4)
@@ -4082,6 +4122,7 @@ class TestMaskedArrayMathMethods:
assert_equal(a.max(-1), [3, 6])
assert_equal(a.max(1), [3, 6])
+ @requires_memory(free_bytes=2 * 10000 * 1000 * 2)
def test_mean_overflow(self):
# Test overflow in masked arrays
# gh-20272
@@ -4089,6 +4130,46 @@ class TestMaskedArrayMathMethods:
mask=np.zeros((10000, 10000)))
assert_equal(a.mean(), 65535.0)
+ def test_diff_with_prepend(self):
+ # GH 22465
+ x = np.array([1, 2, 2, 3, 4, 2, 1, 1])
+
+ a = np.ma.masked_equal(x[3:], value=2)
+ a_prep = np.ma.masked_equal(x[:3], value=2)
+ diff1 = np.ma.diff(a, prepend=a_prep, axis=0)
+
+ b = np.ma.masked_equal(x, value=2)
+ diff2 = np.ma.diff(b, axis=0)
+
+ assert_(np.ma.allequal(diff1, diff2))
+
+ def test_diff_with_append(self):
+ # GH 22465
+ x = np.array([1, 2, 2, 3, 4, 2, 1, 1])
+
+ a = np.ma.masked_equal(x[:3], value=2)
+ a_app = np.ma.masked_equal(x[3:], value=2)
+ diff1 = np.ma.diff(a, append=a_app, axis=0)
+
+ b = np.ma.masked_equal(x, value=2)
+ diff2 = np.ma.diff(b, axis=0)
+
+ assert_(np.ma.allequal(diff1, diff2))
+
+ def test_diff_with_dim_0(self):
+ with pytest.raises(
+ ValueError,
+ match="diff requires input that is at least one dimensional"
+ ):
+ np.ma.diff(np.array(1))
+
+ def test_diff_with_n_0(self):
+ a = np.ma.masked_equal([1, 2, 2, 3, 4, 2, 1, 1], value=2)
+ diff = np.ma.diff(a, n=0, axis=0)
+
+ assert_(np.ma.allequal(a, diff))
+
+
class TestMaskedArrayMathMethodsComplex:
# Test class for miscellaneous MaskedArrays methods.
def setup_method(self):
@@ -4365,6 +4446,7 @@ class TestMaskedArrayFunctions:
assert_equal(test, ctrl)
assert_equal(test.mask, ctrl.mask)
+ @pytest.mark.skipif(IS_WASM, reason="fp errors don't work in wasm")
def test_where(self):
# Test the where function
x = np.array([1., 1., 1., -2., pi/2.0, 4., 5., -10., 10., 1., 2., 3.])
@@ -4504,6 +4586,32 @@ class TestMaskedArrayFunctions:
match="not supported for the input types"):
np.ma.masked_invalid(a)
+ def test_masked_invalid_pandas(self):
+ # getdata() used to be bad for pandas series due to its _data
+ # attribute. This test is a regression test mainly and may be
+ # removed if getdata() is adjusted.
+ class Series():
+ _data = "nonsense"
+
+ def __array__(self):
+ return np.array([5, np.nan, np.inf])
+
+ arr = np.ma.masked_invalid(Series())
+ assert_array_equal(arr._data, np.array(Series()))
+ assert_array_equal(arr._mask, [False, True, True])
+
+ @pytest.mark.parametrize("copy", [True, False])
+ def test_masked_invalid_full_mask(self, copy):
+ # Matplotlib relied on masked_invalid always returning a full mask
+ # (Also astropy projects, but were ok with it gh-22720 and gh-22842)
+ a = np.ma.array([1, 2, 3, 4])
+ assert a._mask is nomask
+ res = np.ma.masked_invalid(a, copy=copy)
+ assert res.mask is not nomask
+ # mask of a should not be mutated
+ assert a.mask is nomask
+ assert np.may_share_memory(a._data, res._data) != copy
+
def test_choose(self):
# Test choose
choices = [[0, 1, 2, 3], [10, 11, 12, 13],
@@ -5499,3 +5607,47 @@ note
original note"""
assert_equal(np.ma.core.doc_note(method.__doc__, "note"), expected_doc)
+
+
+def test_gh_22556():
+ source = np.ma.array([0, [0, 1, 2]], dtype=object)
+ deepcopy = copy.deepcopy(source)
+ deepcopy[1].append('this should not appear in source')
+ assert len(source[1]) == 3
+
+
+def test_gh_21022():
+ # testing for absence of reported error
+ source = np.ma.masked_array(data=[-1, -1], mask=True, dtype=np.float64)
+ axis = np.array(0)
+ result = np.prod(source, axis=axis, keepdims=False)
+ result = np.ma.masked_array(result,
+ mask=np.ones(result.shape, dtype=np.bool_))
+ array = np.ma.masked_array(data=-1, mask=True, dtype=np.float64)
+ copy.deepcopy(array)
+ copy.deepcopy(result)
+
+
+def test_deepcopy_2d_obj():
+ source = np.ma.array([[0, "dog"],
+ [1, 1],
+ [[1, 2], "cat"]],
+ mask=[[0, 1],
+ [0, 0],
+ [0, 0]],
+ dtype=object)
+ deepcopy = copy.deepcopy(source)
+ deepcopy[2, 0].extend(['this should not appear in source', 3])
+ assert len(source[2, 0]) == 2
+ assert len(deepcopy[2, 0]) == 4
+ assert_equal(deepcopy._mask, source._mask)
+ deepcopy._mask[0, 0] = 1
+ assert source._mask[0, 0] == 0
+
+
+def test_deepcopy_0d_obj():
+ source = np.ma.array(0, mask=[0], dtype=object)
+ deepcopy = copy.deepcopy(source)
+ deepcopy[...] = 17
+ assert_equal(source, 0)
+ assert_equal(deepcopy, 17)
diff --git a/numpy/ma/tests/test_extras.py b/numpy/ma/tests/test_extras.py
index 3c95e25ea..d09a50fec 100644
--- a/numpy/ma/tests/test_extras.py
+++ b/numpy/ma/tests/test_extras.py
@@ -12,6 +12,7 @@ import itertools
import pytest
import numpy as np
+from numpy.core.numeric import normalize_axis_tuple
from numpy.testing import (
assert_warns, suppress_warnings
)
@@ -386,8 +387,8 @@ class TestConcatenator:
# Tests mr_ on 2D arrays.
a_1 = np.random.rand(5, 5)
a_2 = np.random.rand(5, 5)
- m_1 = np.round_(np.random.rand(5, 5), 0)
- m_2 = np.round_(np.random.rand(5, 5), 0)
+ m_1 = np.round(np.random.rand(5, 5), 0)
+ m_2 = np.round(np.random.rand(5, 5), 0)
b_1 = masked_array(a_1, mask=m_1)
b_2 = masked_array(a_2, mask=m_2)
# append columns
@@ -729,6 +730,47 @@ class TestCompressFunctions:
assert_equal(c.mask, [[0, 0, 1], [1, 1, 1], [0, 0, 1]])
c = dot(b, a, strict=False)
assert_equal(c, np.dot(b.filled(0), a.filled(0)))
+ #
+ a = masked_array(np.arange(8).reshape(2, 2, 2),
+ mask=[[[1, 0], [0, 0]], [[0, 0], [0, 0]]])
+ b = masked_array(np.arange(8).reshape(2, 2, 2),
+ mask=[[[0, 0], [0, 0]], [[0, 0], [0, 1]]])
+ c = dot(a, b, strict=True)
+ assert_equal(c.mask,
+ [[[[1, 1], [1, 1]], [[0, 0], [0, 1]]],
+ [[[0, 0], [0, 1]], [[0, 0], [0, 1]]]])
+ c = dot(a, b, strict=False)
+ assert_equal(c.mask,
+ [[[[0, 0], [0, 1]], [[0, 0], [0, 0]]],
+ [[[0, 0], [0, 0]], [[0, 0], [0, 0]]]])
+ c = dot(b, a, strict=True)
+ assert_equal(c.mask,
+ [[[[1, 0], [0, 0]], [[1, 0], [0, 0]]],
+ [[[1, 0], [0, 0]], [[1, 1], [1, 1]]]])
+ c = dot(b, a, strict=False)
+ assert_equal(c.mask,
+ [[[[0, 0], [0, 0]], [[0, 0], [0, 0]]],
+ [[[0, 0], [0, 0]], [[1, 0], [0, 0]]]])
+ #
+ a = masked_array(np.arange(8).reshape(2, 2, 2),
+ mask=[[[1, 0], [0, 0]], [[0, 0], [0, 0]]])
+ b = 5.
+ c = dot(a, b, strict=True)
+ assert_equal(c.mask, [[[1, 0], [0, 0]], [[0, 0], [0, 0]]])
+ c = dot(a, b, strict=False)
+ assert_equal(c.mask, [[[1, 0], [0, 0]], [[0, 0], [0, 0]]])
+ c = dot(b, a, strict=True)
+ assert_equal(c.mask, [[[1, 0], [0, 0]], [[0, 0], [0, 0]]])
+ c = dot(b, a, strict=False)
+ assert_equal(c.mask, [[[1, 0], [0, 0]], [[0, 0], [0, 0]]])
+ #
+ a = masked_array(np.arange(8).reshape(2, 2, 2),
+ mask=[[[1, 0], [0, 0]], [[0, 0], [0, 0]]])
+ b = masked_array(np.arange(2), mask=[0, 1])
+ c = dot(a, b, strict=True)
+ assert_equal(c.mask, [[1, 1], [1, 1]])
+ c = dot(a, b, strict=False)
+ assert_equal(c.mask, [[1, 0], [0, 0]])
def test_dot_returns_maskedarray(self):
# See gh-6611
@@ -989,6 +1031,34 @@ class TestMedian:
assert_(r is out)
assert_(type(r) is MaskedArray)
+ @pytest.mark.parametrize(
+ argnames='axis',
+ argvalues=[
+ None,
+ 1,
+ (1, ),
+ (0, 1),
+ (-3, -1),
+ ]
+ )
+ def test_keepdims_out(self, axis):
+ mask = np.zeros((3, 5, 7, 11), dtype=bool)
+ # Randomly set some elements to True:
+ w = np.random.random((4, 200)) * np.array(mask.shape)[:, None]
+ w = w.astype(np.intp)
+ mask[tuple(w)] = np.nan
+ d = masked_array(np.ones(mask.shape), mask=mask)
+ if axis is None:
+ shape_out = (1,) * d.ndim
+ else:
+ axis_norm = normalize_axis_tuple(axis, d.ndim)
+ shape_out = tuple(
+ 1 if i in axis_norm else d.shape[i] for i in range(d.ndim))
+ out = masked_array(np.empty(shape_out))
+ result = median(d, axis=axis, keepdims=True, out=out)
+ assert result is out
+ assert_equal(result.shape, shape_out)
+
def test_single_non_masked_value_on_axis(self):
data = [[1., 0.],
[0., 3.],
diff --git a/numpy/ma/tests/test_old_ma.py b/numpy/ma/tests/test_old_ma.py
index 8465b1153..7b892ad23 100644
--- a/numpy/ma/tests/test_old_ma.py
+++ b/numpy/ma/tests/test_old_ma.py
@@ -194,16 +194,16 @@ class TestMa:
assert_(eq(np.sum(x, axis=0), sum(x, axis=0)))
assert_(eq(np.sum(filled(xm, 0), axis=0), sum(xm, axis=0)))
assert_(eq(np.sum(x, 0), sum(x, 0)))
- assert_(eq(np.product(x, axis=0), product(x, axis=0)))
- assert_(eq(np.product(x, 0), product(x, 0)))
- assert_(eq(np.product(filled(xm, 1), axis=0),
+ assert_(eq(np.prod(x, axis=0), product(x, axis=0)))
+ assert_(eq(np.prod(x, 0), product(x, 0)))
+ assert_(eq(np.prod(filled(xm, 1), axis=0),
product(xm, axis=0)))
if len(s) > 1:
assert_(eq(np.concatenate((x, y), 1),
concatenate((xm, ym), 1)))
assert_(eq(np.add.reduce(x, 1), add.reduce(x, 1)))
assert_(eq(np.sum(x, 1), sum(x, 1)))
- assert_(eq(np.product(x, 1), product(x, 1)))
+ assert_(eq(np.prod(x, 1), product(x, 1)))
def test_testCI(self):
# Test of conversions and indexing
diff --git a/numpy/ma/tests/test_regression.py b/numpy/ma/tests/test_regression.py
index cb3d0349f..f4f32cc7a 100644
--- a/numpy/ma/tests/test_regression.py
+++ b/numpy/ma/tests/test_regression.py
@@ -89,3 +89,9 @@ class TestRegression:
def test_masked_array_tobytes_fortran(self):
ma = np.ma.arange(4).reshape((2,2))
assert_array_equal(ma.tobytes(order='F'), ma.T.tobytes())
+
+ def test_structured_array(self):
+ # see gh-22041
+ np.ma.array((1, (b"", b"")),
+ dtype=[("x", np.int_),
+ ("y", [("i", np.void), ("j", np.void)])])
diff --git a/numpy/ma/tests/test_subclassing.py b/numpy/ma/tests/test_subclassing.py
index 64c66eeb9..e3c885253 100644
--- a/numpy/ma/tests/test_subclassing.py
+++ b/numpy/ma/tests/test_subclassing.py
@@ -154,6 +154,7 @@ class WrappedArray(NDArrayOperatorsMixin):
ufunc deferrals are commutative.
See: https://github.com/numpy/numpy/issues/15200)
"""
+ __slots__ = ('_array', 'attrs')
__array_priority__ = 20
def __init__(self, array, **attrs):
@@ -448,3 +449,12 @@ class TestClassWrapping:
assert_(isinstance(np.divide(wm, m2), WrappedArray))
assert_(isinstance(np.divide(m2, wm), WrappedArray))
assert_equal(np.divide(m2, wm), np.divide(wm, m2))
+
+ def test_mixins_have_slots(self):
+ mixin = NDArrayOperatorsMixin()
+ # Should raise an error
+ assert_raises(AttributeError, mixin.__setattr__, "not_a_real_attr", 1)
+
+ m = np.ma.masked_array([1, 3, 5], mask=[False, True, False])
+ wm = WrappedArray(m)
+ assert_raises(AttributeError, wm.__setattr__, "not_an_attr", 2)