I am trying to make a program that needs a matrix's neighbor(excluding itself) sum ex:
matrix([[0, 0, 0],
[1, 0, 1],
[0, 1, 0]])
would return:
matrix([[1, 2, 1],
[1, 3, 1],
[2, 2, 2]])
I have a working code here but its big and messy and I'm new to numpy so I need some help cleaning it up and optimizing. (I feel like there has to be a better way)
example code:
import numpy as np
def NiSum(m):
new = []
for x in range(m.shape[0]-1):
row = []
for y in range(m.shape[1]-1):
Ni = 0
for a in [1,1],[1,0],[1,-1],[0,1],[0,-1],[-1,1],[-1,0],[-1,-1]:
Ni += m[x+a[0],y+a[1]]
row.append(Ni)
new.append(row)
return np.matrix(new)
example = np.matrix('0 0 0 0 0 0 0 0; '*3+'0 0 0 1 1 1 0 0; '*3+'0 0 0 0 0 0 0 0;0 0 0 0 0 0 0 0 ')
NiSum(example)
Thanks for any help !
You are summing all values in that 3x3 neighbourhood, but excluding the element itself. So, we can use Scipy's 2D convolution and subtract that input array/matrix from it for the desired output, like so -
from scipy.signal import convolve2d
convolve2d(a,np.ones((3,3),dtype=int),'same') - a
Sample run -
In [11]: a
Out[11]:
matrix([[0, 0, 0],
[1, 0, 1],
[0, 1, 0]])
In [12]: convolve2d(a,np.ones((3,3),dtype=int),'same') - a
Out[12]:
matrix([[1, 2, 1],
[1, 3, 1],
[2, 2, 2]])
Or simply form a kernel with all ones but zero at the center and use the same 2D convolution -
In [31]: kernel = np.array([[1,1,1],[1,0,1],[1,1,1]])
In [32]: np.asmatrix(convolve2d(a,kernel,'same'))
Out[32]:
matrix([[1, 2, 1],
[1, 3, 1],
[2, 2, 2]])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With