3

I want to write a function which compares the 8 neighbours of a node in my grid. When minimum of 3 of the neighbours have the same value as the central node, we can define the node as happy.

for example in this array the central node and value is 0, we see that it has 3 neighbours of 0, so the node is happy:

 array([[ 1,  0,  1],
       [ 1,  0,  1],
       [-1,  0,  0]])

I expect an boolean output with True or False.

Can I think of something like this or can I use easily numpy for this?

def nodehappiness(grid, i, j, drempel=3):
    if i,j => 3:
       node == True

Thanks in advance

Adriaan
  • 17,741
  • 7
  • 42
  • 75

4 Answers4

1

Try this:

def neighbours(grid, i, j):
    rows = np.array([-1, -1, -1,  0,  0,  1,  1,  1])
    cols = np.array([-1,  0,  1, -1,  1, -1,  0,  1])
    return grid[rows+i,cols+j]

Edit: Example:

grid = np.arange(25).reshape((5,5))
#array([[ 0,  1,  2,  3,  4],
#       [ 5,  6,  7,  8,  9],
#       [10, 11, 12, 13, 14],
#       [15, 16, 17, 18, 19],
#       [20, 21, 22, 23, 24]])

neighbours(grid, 0, 0)
# array([24, 20, 21,  4,  1,  9,  5,  6])

Explanation:

With numpy you can use negative indices allowing you to easily access the last entries of an array. This will also work for multiple dimensions:

x = np.array([0,1,2,3])
x[-1]
# 3

x.reshape((2,2))
#array([[0, 1],
#       [2, 3]])

x[-1,-1]
# 3

You are interested in 8 entries of the matrix.

  1. left above -> row - 1, column - 1
  2. above -> row - 1, column + 0
  3. right above -> row - 1, column + 1
  4. left -> row + 0, column - 1
  5. ...

Thats what the arrays rows and cols represent. By adding i and j you get all the entries around these coordinates.

markuscosinus
  • 2,248
  • 1
  • 8
  • 19
0

You search something like this?

def neighbour(grid, i, j):
    return np.delete((grid[i-1:i+2,j-1:j+2]).reshape(1,9),4)

# Test code
grid = np.arange(16).reshape(4,4)

b = neighbour(m, 2, 2)
Guille Sanchez
  • 231
  • 1
  • 9
0

Try this.

y=[]
l= len(x)
for i in range(0,l):
    for j in range(0,l):
        if i==int(l/2) and j==int(l/2):
            continue
        y.append(x[j,i])
Vinu Chandran
  • 305
  • 2
  • 10
0

Some hackery using ndimage.generic_filter:

from scipy import ndimage

def get_neighbors(arr):
    output = []
    def f(x):
        output.append(x)
        return 0

    t = tuple(int((x - 1) / 2) for x in arr.shape)
    footprint = np.ones_like(arr)
    footprint[t] = 0
    ndimage.generic_filter(arr, f, footprint=footprint, mode='wrap')
    return np.array(output)

arr = np.arange(9).reshape(3, 3)
neighbors = get_neighbors(arr)
neighbors_grid = neighbors.reshape(*arr.shape, -1)

print(neighbors)
print(neighbors_grid)

Which prints:

# neighbors
[[8. 6. 7. 2. 1. 5. 3. 4.]
 [6. 7. 8. 0. 2. 3. 4. 5.]
 [7. 8. 6. 1. 0. 4. 5. 3.]
 [2. 0. 1. 5. 4. 8. 6. 7.]
 [0. 1. 2. 3. 5. 6. 7. 8.]
 [1. 2. 0. 4. 3. 7. 8. 6.]
 [5. 3. 4. 8. 7. 2. 0. 1.]
 [3. 4. 5. 6. 8. 0. 1. 2.]
 [4. 5. 3. 7. 6. 1. 2. 0.]]

# neighbors_grid
[[[8. 6. 7. 2. 1. 5. 3. 4.]
  [6. 7. 8. 0. 2. 3. 4. 5.]
  [7. 8. 6. 1. 0. 4. 5. 3.]]

 [[2. 0. 1. 5. 4. 8. 6. 7.]
  [0. 1. 2. 3. 5. 6. 7. 8.]
  [1. 2. 0. 4. 3. 7. 8. 6.]]

 [[5. 3. 4. 8. 7. 2. 0. 1.]
  [3. 4. 5. 6. 8. 0. 1. 2.]
  [4. 5. 3. 7. 6. 1. 2. 0.]]]

If you merely want the padded array:

padded = np.pad(arr, pad_width=1, mode='wrap')
print(padded)

Which of course gives:

[[8 6 7 8 6]
 [2 0 1 2 0]
 [5 3 4 5 3]
 [8 6 7 8 6]
 [2 0 1 2 0]]
Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135