As I noted in Optimize a function that acts on a numpy array with an if statement, many ufunc take a where parameter
In this case we can use np.add in such a way:
In [168]: r = np.arange(10)
In [169]: a1 = np.ones(10,int); a1[3:7]=0
In [170]: mask = a1.astype(bool)
In [171]: mask
Out[171]: array([ True, True, True, False, False, False, False, True, True, True], dtype=bool)
In [172]: a2 = np.arange(10,20)
In [173]: a1+a2
Out[173]: array([11, 12, 13, 13, 14, 15, 16, 18, 19, 20])
In [174]: np.add(a1,a2)
Out[174]: array([11, 12, 13, 13, 14, 15, 16, 18, 19, 20])
In [175]: np.add(a1,a2, where=mask, out=r);
In [176]: r
Out[176]: array([11, 12, 13, 3, 4, 5, 6, 18, 19, 20])
Without the out, the where leaves 'random' values in the masked out elements.
In the previous post this where has about the same timing as the masked equivalent.
If you want to use a compound mask, try something like mask = (a1!=0) & (a2>15). The () are important.
np.wherer = a1 + a2*(a1!=0), for zeros intializedr.rnot touching the values wherea1==0