Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: Make mask_invalid consistent with mask_where if copy is set to False #22046

Merged
merged 3 commits into from Oct 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 1 addition & 13 deletions numpy/ma/core.py
Expand Up @@ -2356,20 +2356,8 @@ def masked_invalid(a, copy=True):
fill_value=1e+20)

"""
a = np.array(a, copy=copy, subok=True)
mask = getattr(a, '_mask', None)
if mask is not None:
condition = ~(np.isfinite(getdata(a)))
if mask is not nomask:
condition |= mask
cls = type(a)
else:
condition = ~(np.isfinite(a))
cls = MaskedArray
result = a.view(cls)
result._mask = condition
return result

return masked_where(~(np.isfinite(getdata(a))), a, copy=copy)

###############################################################################
# Printing options #
Expand Down
12 changes: 12 additions & 0 deletions numpy/ma/tests/test_core.py
Expand Up @@ -4496,6 +4496,14 @@ def test_where_structured_masked(self):
assert_equal(ma, expected)
assert_equal(ma.mask, expected.mask)

def test_masked_invalid_error(self):
a = np.arange(5, dtype=object)
a[3] = np.PINF
a[2] = np.NaN
with pytest.raises(TypeError,
match="not supported for the input types"):
np.ma.masked_invalid(a)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We were looking at this in the triage meeting as well. I guess the test is great (I honestly still need to parse it fully).
But we are missing an additional test for the successful path that was fixed I think: Checking that the array was indeed modified in-place with copy=False?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added a new test in test_masked_array_no_copy() ... just to explain myself: I didn't add it in the first place because mask_invalid becomes a straight call of masked_where which is already tested. But I guess the more tests we have the better?
Thanks!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, thanks. It is true that masked_where is tested, but it is also just nice to see the fix in action in the PR and we mainly have integration tests anyway.

A test too much cannot hurt :).

I find it odd that we consider inf invalid by default, but that is not a change.

Thanks @cmarmo, lets get this in!

def test_choose(self):
# Test choose
choices = [[0, 1, 2, 3], [10, 11, 12, 13],
Expand Down Expand Up @@ -5309,6 +5317,10 @@ def test_masked_array_no_copy():
a = np.ma.array([1, 2, 3, 4], mask=[1, 0, 0, 0])
_ = np.ma.masked_where(a == 3, a, copy=False)
assert_array_equal(a.mask, [True, False, True, False])
# check masked array with masked_invalid is updated in place
a = np.ma.array([np.inf, 1, 2, 3, 4])
_ = np.ma.masked_invalid(a, copy=False)
assert_array_equal(a.mask, [True, False, False, False, False])

def test_append_masked_array():
a = np.ma.masked_equal([1,2,3], value=2)
Expand Down