Reputation: 163
I need to find the sum of all the neighboring elements of a cell, say getsumofneighbors(matrix, i, j)
:
'M*N matrix'
[[0 1 0]
[2 0 1]
[0 4 0]
[0 0 0]]
sum of nearest elements of cell [0][0]
is 3
at [1][0]
is 5
and at [1][1]
is 8
Is there a python lib to find the sum of all the elements next to the given cell?
Upvotes: 14
Views: 11122
Reputation: 5167
Following function should accomplish the task of finding the sum of all the neighboring elements of a cell:
def sum_around(matrix, r, c):
total = 0
offset = (0, 1, -1)
indices = ((i, j) for i in offset for j in offset)
next(indices, None)
for rec in indices:
try:
row = r - 1 + rec[0]
col = c - 1 + rec[1]
total += matrix[row][col] if 0 <= row and 0 <= col else 0
except IndexError:
continue
return total
Key points:
offsets defines relative changes needed for given indice to get surrounding elements (incl position of given indice himself because relative change [0][0] results in no change in indice)
due to order of elements in offset, indices generator object created in such way that first item is (0, 0). First item is consumed by next()
looping through generator object remaining elements, calculating and assigning values to matrix indices and adding values to total if indices are not negative (for obvious reasons) and continuing when indices are out of range (IndexError)
function expects that user will enter cell location in finger-based index and deduction -1 is needed for converting values to 0-based index
Upvotes: 0
Reputation: 163
Just created this function which will do the job
def sumofnieghbors(MatrixObj, indexR, indexC):
upperleft = 0
if not (indexR < 1) or (indexC < 1):
upperleft = MatrixObj[indexR - 1][indexC - 1]
upper = 0
if not (indexR < 1):
upper = MatrixObj[indexR - 1][indexC]
upperright = 0
if not ((indexR < 1) or (indexC >= NbofCol)):
upperright = MatrixObj[indexR - 1][indexC + 1]
right = 0
if not (indexC >= NbofCol):
right = MatrixObj[indexR][indexC + 1]
rightdown = 0
if not ((indexR >= NbofRow) or (indexC >= NbofCol)):
rightdown = MatrixObj[indexR + 1][indexC + 1]
down = 0
if not (indexR >= NbofRow):
down = MatrixObj[indexR + 1][indexC]
leftdown = 0
if not ((indexR >= NbofRow) or (indexC < 1)):
leftdown = MatrixObj[indexR + 1][indexC - 1]
left = 0
if not (indexC < 1):
left = MatrixObj[indexR][indexC - 1]
return (upperleft + upper + upperright + right + rightdown + down + leftdown + left)
Upvotes: -3
Reputation: 152860
You can use slicing and np.sum
to calculate the sum of a particular region:
def getsumofneighbors(matrix, i, j):
region = matrix[max(0, i-1) : i+2,
max(0, j-1) : j+2]
return np.sum(region) - matrix[i, j] # Sum the region and subtract center
Notice that the max
is there because negative starting indexes trigger different slicing.
Upvotes: 5
Reputation: 114976
If you don't mind the dependency on scipy, you can use scipy.ndimage.convolve
, as follows:
In [475]: a
Out[475]:
array([[0, 1, 0],
[2, 0, 1],
[0, 4, 0],
[0, 0, 0]])
In [476]: kernel
Out[476]:
array([[1, 1, 1],
[1, 0, 1],
[1, 1, 1]])
In [477]: from scipy.ndimage import convolve
In [478]: c = convolve(a, kernel, mode='constant')
In [479]: c
Out[479]:
array([[3, 3, 2],
[5, 8, 5],
[6, 3, 5],
[4, 4, 4]])
Upvotes: 18
Reputation: 294556
def sum_neighbors(A, i, j):
rows, columns = A.shape
r0, r1 = max(0, i-1), min(rows-1, i+1)
c0, c1 = max(0, j-1), min(columns-1, j+1)
rs = list({r0, i, r1})
cs = [[c] for c in list({c0, j, c1})]
return A[rs, cs].sum() - A[i, j]
Slice A
by row before and after i
with column before and after j
. Take the sum and subtract cell at i
, j
. All other code is to handle the edges.
import numpy as np
mxn = np.array([[0, 1, 0],
[2, 0, 1],
[0, 4, 0],
[0, 0, 0]])
for i, j in [(0, 0), (1, 0), (1, 1)]:
s = "sum of neigbors for i={} and j={} is {}"
print s.format(i, j, sum_neighbors(mxn, i, j))
sum of neigbors for i=0 and j=0 is 3
sum of neigbors for i=1 and j=0 is 5
sum of neigbors for i=1 and j=1 is 8
Upvotes: 1