Search code examples
pythonarraysnumpymasked-array

Return masked array as simple array with masked values as None


I need to mask an array a by a condition fulfilled by another array b.

For example values in a should only be preserved if the values in the same position of b equal 0, otherwise return as None. For example:

a = np.array([2, 2, 4, 0, 4, 3, 3, 3, 1, 2])

is masked by

b = np.array([0, 0, 0, 1, 0, 3, 0, 5, 0, 0])

to return

c: [2, 2, 4, None, 4, None, 3, None, 1, 2]

I have tried

to_change = np.ma.masked_where(travel_time!=0, new_subareas)

but this returns:

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

But I can't find anything that will just return something like the example given for c.

I need something done entirely in numpy and without for-loops or if statements, for speed as this will be for very large arrays. What am I missing?


Solution

  • masked_arrays have a little more overhead, in that operations on these implicitly ignore masked values (and work on everything else instead).

    If you are not looking for that kind of functionality, you can just use np.where, but you risk converting your array to an object.

    np.where(b == 0, a, None)
    array([2, 2, 4, None, 4, None, 3, None, 1, 2], dtype=object)
    

    I'd recommend substitution with NaN instead?

    np.where(b == 0, a, np.nan)
    array([ 2.,  2.,  4., nan,  4., nan,  3., nan,  1.,  2.])
    

    Preserves the numeric type.