Numpy weighted average of 4D array with 2D array of weights without list comprehension
multidimensional-array, numpy, python
Solution
It would be nice to use `np.average` directly. However, to do so, `d` and the weights `e` would have to have the same shape, and broadcasting is not done implicitly for you here.
Explicitly broadcasting `e` (using `np.broadcast_arrays`) so it has same shape as `d` is possible, but a waste of memory. So instead of doing that, would could a peek at the source code defining numpy.average and try to reproduce the calculation:
In [121]: d = np.random.random((16,3,90,144))
In [122]: e = np.random.random((16,3))
In [123]: f = e[:,:,None,None]
In [124]: scl = f.sum(axis = 1)
In [125]: avg = np.multiply(d,f).sum(axis = 1)/scl
Here is a check that the calculation returns the same result as the list comprehension:
In [126]: avg_lc = np.array([np.average(d[n], weights=e[n], axis=0) for n in range(d.shape[0])])
In [127]: np.allclose(avg, avg_lc)
Out[127]: True
Problem
(This question is similar to Numpy averaging with multi-dimensional weights along an axis, but more complicated.) I have a numpy array, `d`, `d.shape=(16,3,90,144)`, and a numpy array of weights, `e`, `e.shape=(16,3)`. I want to take a weighted average of `a` along axis 1 using `e`. So the output should be a numpy array with shape `(16,90,144)`. I can accomplish this with a list comprehension: ``` np.array([np.average(d[n], weights=e[n], axis=0) for n in range(16)]) ``` But as in the previous question, I would like to avoid having to convert from a list back to a numpy array. This case is more complicated than the previous question because the weights aren't the same each time (i.e. `weights=e[n]`, not `weights=b`). Can anybody help? Thanks!