summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Berg <sebastianb@nvidia.com>2023-04-21 12:23:23 +0200
committerCharles Harris <charlesr.harris@gmail.com>2023-04-21 16:47:05 -0600
commit06c26944206ac384597e54c3685706e95b882e52 (patch)
tree8f397555316fa8c8e04639d404ea63505cc4ef17
parent3c6acb51242a4f1067c6ac5159dece8889d19d10 (diff)
downloadnumpy-06c26944206ac384597e54c3685706e95b882e52.tar.gz
BUG: Ignore invalid and overflow warnings in masked setitem
Giving a warning for invalid/overflow in settitem/casts is right (IMO), however for masked arrays it can be surprising since the warning is not useful if the value is invalid but also masked. So, simply blanket ignore the relevant warnings in setitem via errstate. (There may be some other cases like `.astype()` where it might be helpful to MA users to just blanket opt-out of these new warnings.) Closes gh-23000
-rw-r--r--numpy/ma/core.py12
-rw-r--r--numpy/ma/tests/test_core.py18
2 files changed, 30 insertions, 0 deletions
diff --git a/numpy/ma/core.py b/numpy/ma/core.py
index 640abf628..acf1a0444 100644
--- a/numpy/ma/core.py
+++ b/numpy/ma/core.py
@@ -3328,6 +3328,10 @@ class MaskedArray(ndarray):
# Note: Don't try to check for m.any(), that'll take too long
return dout
+ # setitem may put NaNs into integer arrays or occasionally overflow a
+ # float. But this may happen in masked values, so avoid otherwise
+ # correct warnings (as is typical also in masked calculations).
+ @np.errstate(over='ignore', invalid='ignore')
def __setitem__(self, indx, value):
"""
x.__setitem__(i, y) <==> x[i]=y
@@ -4619,6 +4623,7 @@ class MaskedArray(ndarray):
otherwise. 'K' means to read the elements in the order they occur
in memory, except for reversing the data when strides are negative.
By default, 'C' index order is used.
+ (Masked arrays currently use 'A' on the data when 'K' is passed.)
Returns
-------
@@ -4645,6 +4650,13 @@ class MaskedArray(ndarray):
fill_value=999999)
"""
+ # The order of _data and _mask could be different (it shouldn't be
+ # normally). Passing order `K` or `A` would be incorrect.
+ # So we ignore the mask memory order.
+ # TODO: We don't actually support K, so use A instead. We could
+ # try to guess this correct by sorting strides or deprecate.
+ if order in "kKaA":
+ order = "C" if self._data.flags.fnc else "F"
r = ndarray.ravel(self._data, order=order).view(type(self))
r._update_from(self)
if self._mask is not nomask:
diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py
index 8f235062f..203a57853 100644
--- a/numpy/ma/tests/test_core.py
+++ b/numpy/ma/tests/test_core.py
@@ -374,6 +374,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.