简体   繁体   中英

Find number of neighbours in 2D array using convolve2d

I have a 2-dimensional lattice (L*L) with fixed boundaries and considering NSWE sites as 4 neighbours to each site. Each site is assigned an float value. For each site I am calculating average of values of its neighbouring sites added to its own value. I want to solve this using convolv2d from scipy.signal. Following is my code:

# xi_out = constant1*xi + constant2*(sum of xi's neighbours)/no_of_xi's_neighbours

import numpy as np
from scipy.signal import convolve2d

L = 6  # each side of 2D lattice
a, b = (0.1, 0.5) # two constants
arr = np.random.rand(L, L) # example 2D array
# (3,3) window representing 4 neighbours which slides over 'arr'
kernel = np.array([[0, b, 0],
                   [b, a, b],
                   [0, b, 0]])
neighbors_sum = convolve2d(arr, kernel, mode='same', boundary='fill', fillvalue=0)
print(neighbors_sum)

I can not find a way to divide sum of neighbouring values for each site by number of its neighbours.

In following manner I can find number of neighbours for each site but do not know how to incorporate these values into 'result'. Can somebody suggest me how can I achieve that or is there a simpler in-built method in convolve2d to do that ?

arr = np.ones((L,L), dtype=np.int)
kernel = np.array([[0, 1, 0],
                   [1, 0, 1],
                   [0, 1, 0]])
neighbors_count = convolve2d(arr, kernel, mode='same', boundary='fill', fillvalue=0)
print(neighbors_count)

To divide one array by another, element-by-element, use np.divide :

np.divide(result, neighbours_count)

Looks like this is all that needs to be added to your code; I think it's pretty good as is.

Generally, to find a weighted average of some sort, one can do the following:

  1. Perform summation with weights on the input array.
  2. Perform the same on the array of ones, of the same size as the input.
  3. Divide the result of 1 by the result of 2.
import numpy as np
from scipy.signal import convolve2d

L = 6
a, b = 0.1, 0.5

arr = np.random.rand(L, L)
arrb = arr.astype(bool)
kernel = np.array([[0, 1, 0],
                   [1, 0, 1],
                   [0, 1, 0]])

neighbors_sum = convolve2d(arr, kernel, mode='same', boundary='fill', fillvalue=0)
neighbors_count = convolve2d(arrb, kernel, mode='same', boundary='fill', fillvalue=0)
neighbors_mean = np.divide(neighbors_sum, neighbors_count)
res = a * arr + b * neighbors_mean
print(res)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM