diff options
author | Sebastian Berg <sebastianb@nvidia.com> | 2023-04-21 12:23:23 +0200 |
---|---|---|
committer | Charles Harris <charlesr.harris@gmail.com> | 2023-04-21 16:47:05 -0600 |
commit | 06c26944206ac384597e54c3685706e95b882e52 (patch) | |
tree | 8f397555316fa8c8e04639d404ea63505cc4ef17 | |
parent | 3c6acb51242a4f1067c6ac5159dece8889d19d10 (diff) | |
download | numpy-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.py | 12 | ||||
-rw-r--r-- | numpy/ma/tests/test_core.py | 18 |
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. |