8000 BUG: Make ma.where work with structured types. by charris · Pull Request #5827 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

BUG: Make ma.where work with structured types. #5827

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

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
BUG: Make ma.where work with structured types.
Closes #5826.
  • Loading branch information
charris committed May 2, 2015
commit ad85c4710b1e75b93bd61d8e0b5ec32b31826c6f
18 changes: 9 additions & 9 deletions numpy/ma/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -6766,7 +6766,6 @@ def where(condition, x=_NoValue, y=_NoValue):

# Get the condition
fc = filled(condition, 0).astype(MaskType)
notfc = np.logical_not(fc)

# Get the data
xv = getdata(x)
Expand All @@ -6779,18 +6778,19 @@ def where(condition, x=_NoValue, y=_NoValue):
ndtype = np.find_common_type([xv.dtype, yv.dtype], [])

# Construct an empty array and fill it
d = np.empty(fc.shape, dtype=ndtype).view(MaskedArray)
np.copyto(d._data, xv.astype(ndtype), where=fc)
np.copyto(d._data, yv.astype(ndtype), where=notfc)
data = np.where(fc, xv.astype(ndtype), yv.astype(ndtype))
d = data.view(MaskedArray)

# Create an empty mask and fill it
mask = np.zeros(fc.shape, dtype=MaskType)
np.copyto(mask, getmask(x), where=fc)
np.copyto(mask, getmask(y), where=notfc)
mask |= getmaskarray(condition)
mask = np.where(fc, getmaskarray(x), getmaskarray(y))
Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry for not simply trying, but a bit in a rush: would you not need to create a new mask type, in analogy with the ndtype above? I.e., will this work as expected when one or both of the mask arrays have a record dtype?

Copy link
Contributor

Choose a reason for hiding this comment

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

Oops, sorry, find_common_type is not an issue here, that is just for float, etc.

np.copyto(mask, True, where=getmaskarray(condition))

if isinstance(mask.dtype.type, np.void):
needmask = np.any(np.ones(1, mask.dtype) == mask)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this would mean that if there is a record in which only one element is masked, needmask would be False. If so, you'd want

needmask = not np.all(np.zeros(1, mask.dtype) == mask)

Copy link
Contributor

Choose a reason for hiding this comment

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

Looking at this again afresh, I think this comment is indeed correct: if one does equality for a record mask, all elements are considered for each item, so we only can dispense with the mask if all items have no elements masked.

Note that I think the if-statement can be if mask.dtype.names:

else:
needmask = np.any(mask)
# Use d._mask instead of d.mask to avoid copies
d._mask = mask if mask.any() else nomask
d._mask = mask if needmask else nomask

return d

Expand Down
0