Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 313
MoMiJi Avatar asked Jan 28 '23 10:01

MoMiJi


2 Answers

If you need an in-place solution, you can convert to a to float and then use np.where.

Float conversion is required here as np.nan is a float.

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

a = a.astype(float)
a[np.where(b!=0)] = np.nan

# array([  2.,   2.,   4.,  nan,   4.,  nan,   3.,  nan,   1.,   2.])
like image 36
jpp Avatar answered Jan 31 '23 00:01

jpp


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.

like image 200
cs95 Avatar answered Jan 30 '23 23:01

cs95