I have a numpy array like this:
x = np.array([[1,2,3],[4,5,6],[7,8,9]])
I need to create a function let's call it "neighbors" with the following input parameter:
As output I want to get the neighbors of the cell i,j
with a given distance d
.
So if I run
neighbors(im, i, j, d=1) with i = 1 and j = 1 (element value = 5)
I should get the indices of the following values: [1,2,3,4,6,7,8,9]
. I hope I make it clear.
Is there any library like scipy which deal with this?
I've done something working but it's a rough solution.
def pixel_neighbours(self, p):
rows, cols = self.im.shape
i, j = p[0], p[1]
rmin = i - 1 if i - 1 >= 0 else 0
rmax = i + 1 if i + 1 < rows else i
cmin = j - 1 if j - 1 >= 0 else 0
cmax = j + 1 if j + 1 < cols else j
neighbours = []
for x in xrange(rmin, rmax + 1):
for y in xrange(cmin, cmax + 1):
neighbours.append([x, y])
neighbours.remove([p[0], p[1]])
return neighbours
How can I improve this?
Have a look at scipy.ndimage.generic_filter
.
As an example:
import numpy as np
import scipy.ndimage as ndimage
def test_func(values):
print values
return values.sum()
x = np.array([[1,2,3],[4,5,6],[7,8,9]])
footprint = np.array([[1,1,1],
[1,0,1],
[1,1,1]])
results = ndimage.generic_filter(x, test_func, footprint=footprint)
By default, it will "reflect" the values at the boundaries. You can control this with the mode
keyword argument.
However, if you're wanting to do something like this, there's a good chance that you can express your problem as a convolution of some sort. If so, it will be much faster to break it down into convolutional steps and use more optimized functions (e.g. most of scipy.ndimage
).