Как предлагается в комментариях, он работает со сверткой сигнала:
from scipy import signal
kernel = np.array([[1,1,1],[1,1,1],[1,1,1]])
grad = signal.convolve2d(data, kernel, 'same')
grad = grad/9
, затем вы делите матрицу на количество элементов в матрице ядра, для матрицы 3x3 вы делите на 9. Это работаетс меньшими и большими матрицами.
Больше теории здесь, мне очень помогло понять замысловатую функцию: machinelearninguru.com
Если вы не хотите использоватьscipy, он будет работать также только с numy: Пример NumPy
Если средства для углов и ребер должны отражать только ячейку и ее соседейделитель для результата convolve2d
может быть построен как:
corners = (np.array([0,0,-1,-1], dtype=np.int32),np.array([0,-1,0,-1], dtype=np.int32))
edges = np.ones(data.shape, dtype=np.bool)
edges[1:-1,1:-1] = False
edges[corners] = False
divisor = np.ones(data.shape) * 9
divisor[corners] = 4
divisor[edges] = 6
grad = signal.convolve2d(data, kernel, 'same')
grad = grad / divisor
Для начального массива data = np.arange(1, (5*3)+1).reshape((5, 3))
это приводит к:
In [35]: data
Out[35]:
array([[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12],
[13, 14, 15]])
In [36]: divisor
Out[36]:
array([[ 4., 6., 4.],
[ 6., 9., 6.],
[ 6., 9., 6.],
[ 6., 9., 6.],
[ 4., 6., 4.]])
In [37]: grad
Out[37]:
array([[ 3. , 3.5, 4. ],
[ 4.5, 5. , 5.5],
[ 7.5, 8. , 8.5],
[ 10.5, 11. , 11.5],
[ 12. , 12.5, 13. ]])