You are essentially trying to write a filter for your array.
First you need to write a function that when given an array of values, with the middle one being the element currently examined, will return some computation of those values. In your case the function will expect to take 1-d array and returns the element nearest to the middle index that is not cloud:
import numpy as np
from scipy.ndimage.filters import generic_filter
_cloud = -1
def findNearestNonCloud(elements):
middleIndex = len(elements) / 2
if elements[middleIndex] != _cloud:
return elements[middleIndex] # middle value is not cloud
nonCloudIndices, = np.where(elements != _cloud)
if len(nonCloudIndices) == 0:
return elements[middleIndex] # all values were cloud
prevNonCloudIndex = np.where(nonCloudIndices < middleIndex,
nonCloudIndices, -1).max()
nextNonCloudIndex = -np.where(nonCloudIndices > middleIndex,
-nonCloudIndices, 1).min()
# -1 means no non-cloud index
# pick index closest to middle index
if (abs(prevNonCloudIndex - middleIndex)
<= abs(nextNonCloudIndex - middleIndex)):
return elements[prevNonCloudIndex]
else:
return elements[nextNonCloudIndex]
Now you need to apply this function to the elements you're interesting. To do this you'll need a mask that denotes which other elements you'll be interested in with regard to a specific element.
from scipy.ndimage.filters import generic_filter
# creates 5 days worth of a 3x3 plot of land
input = np.ones((5, 3, 3)) * _cloud
input[0,:,:] = 10 # set first "image" to all be 10s
input[4,0,0] = 12 # uppper left corner of fourth image is set to 12
print "input data\n", input, "\n"
mask = (5, 1, 1)
# mask represents looking at the present day, 2 days in the future and 2 days in
# the past for 5 days in total.
print "result\n", generic_filter(input, findNearestNonCloud, size=mask)
# second and third images should mirror first image,
# except upper left corner of third image should be 12