2

I created an index based on several conditions

transition = np.where((rain>0) & (snow>0) & (graup>0) & (xlat<53.) & (xlat>49.) & (xlon<-114.) & (xlon>-127.)) #indexes the grids where there are transitions

with the shape of (3,259711) that looks like the following:

array([[  0,   0,   0, ...,  47,  47,  47], #hour
       [847, 847, 848, ..., 950, 950, 951], #lat gridpoint
       [231, 237, 231, ..., 200, 201, 198]]) #lon gridpoint

I have several other variables (e.g. temp) with the shape of (48, 1015, 1359) corresponding to hour, lat, lon.

Seeing as the index are my valid gridpoints, how do I mask all the variables, like temp so that it retains the (48,1015,1359) shape, but masks the values outside the index.

4
  • What exactly do you mean by mask? For what kind of operation? For somethings a masked array (np.ma) subclass might be useful. Commented Feb 1, 2017 at 17:47
  • Thanks for the suggestion. I have already tried using numpy.ma.masked_where(idx, temp), but I have issues with my shape IndexError: Inconsistant shape between the condition and the input (got (3, 259711) and (48, 1015, 1359)) @hpaulj Commented Feb 1, 2017 at 18:08
  • masked_where wants the boolean mask of values you want hidden, not the index tuple produced by where. What's the condition matrix that produced this where tuple? Commented Feb 1, 2017 at 19:10
  • @hpaulj Hmm, ah okay, is there a way to use the index (using np.where), so that those indices are not masked, while the rest are masked? Commented Feb 1, 2017 at 20:49

1 Answer 1

1
In [90]: arr = np.arange(24).reshape(6,4)
In [91]: keep = (arr % 3)==1
In [92]: keep
Out[92]: 
array([[False,  True, False, False],
       [ True, False, False,  True],
       [False, False,  True, False],
       [False,  True, False, False],
       [ True, False, False,  True],
       [False, False,  True, False]], dtype=bool)
In [93]: np.where(keep)
Out[93]: 
(array([0, 1, 1, 2, 3, 4, 4, 5], dtype=int32),
 array([1, 0, 3, 2, 1, 0, 3, 2], dtype=int32))

Simple application of the keep mask gives a 1d array of the desired values. I could also index with the where tuple.

In [94]: arr[keep]
Out[94]: array([ 1,  4,  7, 10, 13, 16, 19, 22])

With keep, or rather it's boolean inverse, I can make a masked array:

In [95]: np.ma.masked_array(arr,mask=~keep)
Out[95]: 
masked_array(data =
 [[-- 1 -- --]
 [4 -- -- 7]
 [-- -- 10 --]
 [-- 13 -- --]
 [16 -- -- 19]
 [-- -- 22 --]],
             mask =
 [[ True False  True  True]
 [False  True  True False]
 [ True  True False  True]
 [ True False  True  True]
 [False  True  True False]
 [ True  True False  True]],
       fill_value = 999999)

np.ma.masked_where(~keep, arr) does the same thing - just a different argument order. It still expects the boolean mask array.

I can do the same starting with the where tuple:

In [105]: idx = np.where(keep)
In [106]: mask = np.ones_like(arr, dtype=bool)
In [107]: mask[idx] = False
In [108]: np.ma.masked_array(arr, mask=mask)

There may be something in the np.ma class that does this with one call, but it will have to do the same sort of construction.

This also works:

x = np.ma.masked_all_like(arr)
x[idx] = arr[idx]
Sign up to request clarification or add additional context in comments.

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.