0

It is possible to compute the average of a numpy array over multiple dimensions, as in eg. my_ndarray.mean(axis=(1,2)).

However, it does not seem to work with a masked array:

>>> import numpy as np
>>> a = np.random.randint(0, 10, (2, 2, 2))
>>> a
array([[[0, 9],
        [2, 5]],

       [[8, 6],
        [0, 7]]])
>>> a.mean(axis=(1, 2))
array([ 4.  ,  5.25])
>>> ma = np.ma.array(a, mask=(a < 5))
>>> ma.mean(axis=(1, 2))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/site-packages/numpy/ma/core.py", line 5066, in mean
    cnt = self.count(axis=axis)
  File "/usr/lib/python2.7/site-packages/numpy/ma/core.py", line 4280, in count
    n1 = np.size(m, axis)
  File "/usr/lib/python2.7/site-packages/numpy/core/fromnumeric.py", line 2700, in size
    return a.shape[axis]
TypeError: tuple indices must be integers, not tuple

How can I compute the average of a masked array over multiple axis, preferably as simply as it would be for a normal array?

(I would rather use a solution that does not implies defining a new function, as proposed in this answer.)

4
  • Have you tried ma.mean(2).mean(1)? Commented Apr 20, 2016 at 15:29
  • @wflynny : This answer should work. In case, that he only wants to compute the average of the 'not-masked-values'. Commented Apr 20, 2016 at 15:33
  • For more details on the tuple indexing not being implemented see this question, too. Commented Apr 20, 2016 at 15:37
  • @wflynny: this was my first guess but it changes the weight given to each value. With the previous eg. it returns [7, 7.25] instead of [7, 7] as it should. (Plus, it would be ma.mean(1).mean(1).) Commented Apr 20, 2016 at 15:42

2 Answers 2

2

I found out that though np.ma.mean does not works, np.ma.average gives the expected result:

>>> np.ma.average(ma, axis=(1,2))
masked_array(data = [7.0 7.0],
             mask = [False False],
       fill_value = 1e+20)

This is confusing since for regular array, np.average is a mere wrapper around np.mean. But as long as it works, I won’t complain!

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

Comments

0

You can reshape it before the mean :

>>>ma.reshape(mc.shape[0],-1).mean(1)
masked_array(data = [1.6666666666666667 4.0],
         mask = [False False],
         fill_value = 1e+20)

Note that partial application of averaging lead to ambiguous results :

>>> ma.mean(1).mean(1)
masked_array(data = [1.5 4.0],
             mask = [False False],
       fill_value = 1e+20)


>>> ma.mean(2).mean(1)
masked_array(data = [2.25 4.0],
             mask = [False False],
       fill_value = 1e+20)

Explained by :

>>>ma
masked_array(data =
 [[[0 1]
  [4 --]]

 [[-- --]
  [-- 4]]],
             mask =
 [[[False False]
  [False  True]]

 [[ True  True]
  [ True False]]],
       fill_value = 999999)

The weights are not the same in each case.

To average on other dimensions, you can use np.rollaxis before.

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.