0

I would like to replace by zero value all my masked values in 2D array. I saw with np.copyto it was apparently possible to do that as :

test=np.copyto(array, 0, where = mask)

But i have an error message...'module' object has no attribute 'copyto'. Is there an equivalent way to do that?

1
  • 1
    array[mask] = 0 or using np.where Commented Nov 16, 2014 at 11:51

2 Answers 2

4

Try numpy.ma.filled() I think this is exactly what you need

In [29]: a
Out[29]: array([ 1,  0, 25,  0,  1,  4,  0,  2,  3,  0])
In [30]: am = n.ma.MaskedArray(n.ma.log(a),fill_value=0)
In [31]: am
Out[31]: 
masked_array(data = [0.0 -- 3.2188758248682006 -- 0.0 1.3862943611198906 --  0.6931471805599453  1.0986122886681098 --], 
mask = [False  True False  True False False  True False False  True],
fill_value = 0.0)
In [32]: am.filled()
Out[32]: 
array([ 0.        ,  0.        ,  3.21887582,  0.        ,  0.        ,
    1.38629436,  0.        ,  0.69314718,  1.09861229,  0.        ])
Sign up to request clarification or add additional context in comments.

Comments

1

test = np.copyto(array, 0, where=mask) is equivalent to:

array = np.where(mask, 0, array)
test = None

(I'm not sure why you would want to assign a value to the return value of np.copyto; it always returns None if no Exception is raised.)


Why not use array[mask] = 0?

Indeed, that would work (and has nicer syntax) if mask is a boolean array with the same shape as array. If mask doesn't have the same shape then array[mask] = 0 and np.copyto(array, 0, where=mask) may behave differently:

np.copyto (is documented to) and np.where (appears to) broadcast the shape of the mask to match array. In contrast, array[mask] = 0 does not broadcast mask. This leads to a big difference in behavior when the mask does not have the same shape as array:

In [60]: array = np.arange(12).reshape(3,4)

In [61]: mask = np.array([True, False, False, False], dtype=bool)

In [62]: np.where(mask, 0, array)
Out[62]: 
array([[ 0,  1,  2,  3],
       [ 0,  5,  6,  7],
       [ 0,  9, 10, 11]])

In [63]: array[mask] = 0

In [64]: array
Out[64]: 
array([[ 0,  0,  0,  0],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

When array is 2-dimensional and mask is a 1-dimensional boolean array, array[mask] is selecting rows of array (where mask is True) and array[mask] = 0 sets those rows to zero.

Surprisingly, array[mask] does not raise an IndexError even though the mask has 4 elements and array only has 3 rows. No IndexError is raised when the fourth value is False, but an IndexError is raised if the fourth value is True:

In [91]: array[np.array([True, False, False, False])]
Out[91]: array([[0, 1, 2, 3]])

In [92]: array[np.array([True, False, False, True])]
IndexError: index 3 is out of bounds for axis 0 with size 3

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.