python numpy weighted average with nans

numpy, python

Solution

First find out indices where the items are not `nan`, and then pass the filtered versions of `a` and `weights` to `numpy.average`:

>>> import numpy as np
>>> a = np.array([1, 2, np.nan,4])
>>> weights = np.array([4, 3, 2, 1])
>>> indices = np.where(np.logical_not(np.isnan(a)))[0]
>>> np.average(a[indices], weights=weights[indices])
1.75

As suggested by @mtrw in comments, it would be cleaner to use masked array here instead of index array:

>>> indices = ~np.isnan(a)
>>> np.average(a[indices], weights=weights[indices])
1.75

Problem

First things first: this is not a duplicate of NumPy: calculate averages with NaNs removed, i'll explain why: Suppose I have an array ``` a = array([1,2,3,4]) ``` and I want to average over it with the weights ``` weights = [4,3,2,1] output = average(a, weights=weights) print output 2.0 ``` ok. So this is pretty straightforward. But now I have something like this: ``` a = array([1,2,nan,4]) ``` calculating the average with the usual method yields of course`nan`. Can I avoid this? In principle I want to ignore the nans, so I'd like to have something like this: ``` a = array([1,2,4]) weights = [4,3,1] output = average(a, weights=weights) print output 1.75 ```

Original source

Related problems