6

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?

cs95
  • 379,657
  • 97
  • 704
  • 746
MoMiJi
  • 93
  • 1
  • 1
  • 9

2 Answers2

7

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.

cs95
  • 379,657
  • 97
  • 704
  • 746
  • Perfect and much simpler, especially with np.nan as I am trying to preserve the numeric type, thank you. – MoMiJi Mar 23 '18 at 16:15
1

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.])
jpp
  • 159,742
  • 34
  • 281
  • 339