Duncan WP
Duncan WP

Reputation: 880

Numpy broadcast_to for masked array

I'm using the np.broadcast_to function to get a view on a reshaped array just like the example:

>>> x = np.array([1, 2, 3])
>>> np.broadcast_to(x, (3, 3))
array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]])

Passing a masked array to this function loses me the mask though:

>>> y = np.ma.array([1, 2, 3], mask=[False, True, False])
>>> np.broadcast_to(y, (3, 3))
array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]])

How do I get the following view?

array([[1, --, 3],
       [1, --, 3],
       [1, --, 3]])

Upvotes: 3

Views: 2564

Answers (3)

Chappy Hickens
Chappy Hickens

Reputation: 445

Building on @Sandeep Kadapa's helpful result (I lack the reputation to comment), I built a function that can be used to find and replace calls of numpy.broadcast_to:

import numpy as np

def ma_broadcast_to(maskedarray,tup):
        initial_mask=np.ma.getmask(maskedarray)
        broadcasted_mask=np.broadcast_to(initial_mask,tup)
        broadcasted_array=np.broadcast_to(maskedarray,tup)
        return np.ma.array(broadcasted_array, mask=broadcasted_mask)

and applied to the OP

y = np.ma.array([1, 2, 3], mask=[False, True, False])
ma_broadcast_to(y,(3,3))

returns

masked_array(
  data=[[1, --, 3],
        [1, --, 3],
        [1, --, 3]],
  mask=[[False,  True, False],
        [False,  True, False],
        [False,  True, False]],
  fill_value=999999)

Upvotes: 0

Space Impact
Space Impact

Reputation: 13255

I think this is what you want. Mask the array after broadcast, So that you get the desired masked array.

y = np.ma.array([1, 2, 3])
z = np.broadcast_to(y, (3, 3))
x = np.ma.array(z, mask=np.broadcast_to([False,True,False], (3, 3)))
x
masked_array(data =
 [[1 -- 3]
 [1 -- 3]
 [1 -- 3]],
             mask =
 [[False  True False]
 [False  True False]
 [False  True False]],
       fill_value = 999999)

Check if this worked for your case. If you want the masked array values without '--'

x.compressed()
array([1, 3, 1, 3, 1, 3])

For more information go through Masked array documentation

Upvotes: 1

Moses Koledoye
Moses Koledoye

Reputation: 78564

Apparently, you can pass a subok parameter to np.broadcast_to to retain the type of the passed array and not use the base array type, but this only broadcasts the data of the masked array, not the mask.

You should probably manually broadcast the mask afterwards:

>>> y = np.ma.array([1, 2, 3], mask=[False, True, False])
>>> z = np.broadcast_to(y, (3, 3), subok=True)
>>> z.mask
False
>>> z.mask = np.broadcast_to(y.mask, z.shape)
>>> z
masked_array(data =
 [[1 -- 3]
 [1 -- 3]
 [1 -- 3]],
             mask =
 [[False  True False]
 [False  True False]
 [False  True False]],
       fill_value = 999999)

Upvotes: 4

Related Questions