0
m =  np.array([[[0.4,0.5],[0.2,0.3]], [[0.8,0.1],[0.7,0.9]]])
id = np.array([[[1,2],[2,3]], [[3,1],[3,2]]])
mask = np.array([[[0,1],[1,0]], [[1,1],[1,1]]])

I'd like to calculate the mean of m for each index in id, and only for nonzero elements in mask.

For example for id==3, that would be the mean of [0.8,0.7].

I thought np.ma.masked_array.mean would do the trick but this does not give me the expected output

 >> np.ma.masked_array(m[id==3],mask=mask[id==3]).mean()
    0.29999999
0

2 Answers 2

3

Simple array indexing should work:

import numpy as np

m =  np.array([[[0.4,0.5],[0.2,0.3]], [[0.8,0.1],[0.7,0.9]]])
my_id = np.array([[[1,2],[2,3]], [[3,1],[3,2]]])
mask = np.array([[[0,1],[1,0]], [[1,1],[1,1]]])

print(m[(mask != 0) & (my_id == 3)])          # [0.8 0.7]
print(m[(mask != 0) & (my_id == 3)].mean())   # 0.75

Also, id is a built-in function, so don't name a variable that. It will shadow the built-in.

Sign up to request clarification or add additional context in comments.

Comments

2

Apply the mask to both m and id_ and then use np.bincount

m =  np.array([[[0.4,0.5],[0.2,0.3]], [[0.8,0.1],[0.7,0.9]]])
id_ = np.array([[[1,2],[2,3]], [[3,1],[3,2]]])
mask = np.array([[[0,1],[1,0]], [[1,1],[1,1]]])

mask = mask.astype(bool)
mm, idm = m[mask], id_[mask]
result = np.bincount(idm, mm)/np.bincount(idm)

result
# array([       nan, 0.1       , 0.53333333, 0.75      ])

result contains all the means, for example result[3] is the mean for id_ 3.

Note: your approach does not work because by convention in a masked array the mask specifies the missing not the valid data, in other words you'd have to invert the mask.

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.