17

I Want to write the code below as Pythonic way, applying mean over two axis. What the best way to do this?

import numpy as np

m = np.random.rand(30, 10, 10)  
m_mean = np.zeros((30, 1))    
for j in range(30):
    m_mean[j, 0] = m[j, :, :].mean()
Gilad Green
  • 36,708
  • 7
  • 61
  • 95
marcelorodrigues
  • 919
  • 5
  • 12
  • 22

2 Answers2

38

If you have a sufficiently recent NumPy, you can do

m_mean = m.mean(axis=(1, 2))

I believe this was introduced in 1.7, though I'm not sure. The documentation was only updated to reflect this in 1.10, but it worked earlier than that.

If your NumPy is too old, you can take the mean a bit more manually:

m_mean = m.sum(axis=2).sum(axis=1) / np.prod(m.shape[1:3])

These will both produce 1-dimensional results. If you really want that extra length-1 axis, you can do something like m_mean = m_mean[:, np.newaxis] to put the extra axis there.

user2357112
  • 260,549
  • 28
  • 431
  • 505
  • With older numpy, you can also just do `m.mean(axis=2).mean(axis=1)` – Rob Sep 09 '20 at 08:08
  • @Rob: Ah, you're right. Since all the means in the `m.mean(axis=2)` step are over the same number of elements, `m.mean(axis=2).mean(axis=1)` correctly gives each element equal weight. – user2357112 Sep 09 '20 at 14:04
2

You can also use the numpy.mean() ufunc and pass the output array as an argument to out= as in:

np.mean(m, axis=(1, 2), out=m_mean)
kmario23
  • 57,311
  • 13
  • 161
  • 150