Search code examples
pythonarrayslistnumpyneighbours

Python Numpy Array geht values of neighbours


I want to get all neighbour values of a np.array.

The array looks like:

x = np.array([  [1, 2, 3, 4 ],
                [5, 6, 7, 8],
                [9, 10, 11, 12],
                [13, 14, 15, 16] ])

What I have is:

i = 2
j = 2

n = x[i,j-1], x[i,j], x[i,j+1], x[i-1,j], x[i+1,j], x[i-1,j-1], x[i+1,j+1], x[i+1,j-1], x[i-1,j+1]

This returns (what I want)

(10, 11, 12, 7, 15, 6, 16, 14, 8)

But also got bugs for example when i want the neightbour values of

i = 3
j = 3

That gives:

Exception has occurred: IndexError
index 4 is out of bounds for axis 1 with size 4

An other soultion is:

def find_neighbors(m, i, j, dist=1):
    return [row[max(0, j-dist):j+dist+1] for row in m[max(0,-1):i+dist+1]]

and

n = find_neighbors(x, i, j)

Which gives me an array of the neightbours but also gives me not all neightbours when I set

i = 0
j = 0

because it only gives me:

[array([1, 2]), array([5, 6])]

Does anybody have a solution for this?

Thank you!


Solution

  • You can take advantage of python indexing wrapping around for negative indices.

    def wrap_nb(x,i,j):
        return x[np.ix_(*((z-1, z, z+1-S) for z,S in zip((i,j), x.shape)))].ravel()
    

    This requires i and j to be nonnegative and less than the shape of x.

    If that is not guaranteed:

    def wrap_nb(x,i,j):
        return x[np.ix_(*(np.r_[z-1:z+2]%S for z,S in zip((i,j), x.shape)))].ravel()
    

    Examples:

    >>> wrap_nb(x,1,-2)
    array([ 2,  3,  4,  6,  7,  8, 10, 11, 12])
    >>> wrap_nb(x,0,-1)
    array([15, 16, 13,  3,  4,  1,  7,  8,  5])
    >>> wrap_nb(x,0,0)
    array([16, 13, 14,  4,  1,  2,  8,  5,  6])