From a list of 2D coordinates, and a third variable (velocity), I have created a 2D numpy array covering the whole sampled area. My intention is to create an image, in which each pixel contains the mean velocity of the points lying within it. After that filter that image with a gaussian filter.
The problem is that the area is not uniformly sampled. Therefore I have several pixels without information (Nan
) in the middle of the image. When I try to filter the array through a gaussian filter, the Nan
propagate ruining the whole image.
I need to filter this image, but rejecting all pixels without information. In other words, If a pixel does not contain information, then it should be not taken into account for the filtering.
Here is an example of my code for averaging:
Mean_V = np.zeros([len(x_bins), len(y_bins)])
for i, x_bin in enumerate(x_bins[:-1]):
bin_x = (x > x_bins[i]) & (x <= x_bins[i+1])
for j, y_bin in enumerate(y_bins[:-1]):
bin_xy = (y[bin_x] > y_bins[j]) & (y[bin_x] <= y_bins[j+1])
if (sum(x > 0 for x in bin_xy) > 0) :
Mean_V[i,j]=np.mean(V[bin_x][bin_xy])
else:
Mean_V[i,j]=np.nan
EDIT:
Surfing the web I have ended into this question I made in 2013. The solution to this problem can be found in the astropy library:
http://docs.astropy.org/en/stable/convolution/
Astropy's convolution replaces the NaN pixels with a kernel-weighted interpolation from their neighbors.
Thanks folks!!
I stepped over this question a while ago and used davids answer (thanks!). As it turned out in the meantime, the task of applying a gaussian filter to a array with nans is not as well defined as I thought.
As descibed in ndimage.gaussian_filter, there are different options to process values at the border of the image (reflection, constant extrapolation, ...). A similar decision has to be made for the nan values in the image.
filter_nan_gaussian_david
: Davids approach is equivalent to assuming some mean-neighborhood-value at each nan-point. This leads to a change in the total intensity (seesum
value in colum 3), but does a great job otherwise.filter_nan_gaussian_conserving
: This approach is to spead the intesity of each point by a gaussian filter. The intensity, which is mapped to nan-pixels is reshifted back to the origin. If this maskes sense, depends on the application. I have a closed area surronded by nans and want to preseve the total intensity + avoid distortions at the boundaries.filter_nan_gaussian_conserving2
: Speads intesity of each point by a gaussian filter. The intensity, which is mapped to nan-pixels is redirected to the other pixels with the same Gaussian weighting. This leads to a relative reduction of the intensity at the origin in the vicinity of many nans / border pixels. This is illustrated in the last row very right.Code