python - Weighted array of neighbors for each element in a numpy array -
i have numpy array(a) , weights matrix(say m, sort of filter). want apply filter @ each element of , array of neighbors multiplied m each element of a.
for example, if m 3x3 kernel, get:
for each (i,j), a[i,j] --> array([a[i-1,j-1]*m[0,0], a[i-1,j]*m[0,1],...,a[i+1,j+1]*m[2,2]])
so, output have 1 dimension more a. preferably border cases, need consider partial filter(equivalent padding zeros). there way efficiently?
here's approach using skimage's view_as_windows gives sliding windows of required kernel shape -
from skimage.util import view_as_windows vieww # pad 1 layer of zeros around input array a1 = np.lib.pad(a, (1,1), 'constant', constant_values=0) # create 3x3 sliding windows each elem , multiply m. # reshape each window 9 elem list per requirement. out = (vieww(a1,[3,3])*m).reshape(a.shape + (9,)) sample run :
1] input array -
in [64]: out[64]: array([[75, 46, 74, 72, 96], [44, 72, 41, 81, 50], [16, 70, 22, 19, 49], [87, 74, 78, 66, 49]]) 2] input array padded -
in [65]: a1 out[65]: array([[ 0, 0, 0, 0, 0, 0, 0], [ 0, 75, 46, 74, 72, 96, 0], [ 0, 44, 72, 41, 81, 50, 0], [ 0, 16, 70, 22, 19, 49, 0], [ 0, 87, 74, 78, 66, 49, 0], [ 0, 0, 0, 0, 0, 0, 0]]) 3] 3d output array -
in [66]: out out[66]: array([[[ 0, 0, 0, 0, 450, 276, 0, 220, 504], [ 0, 0, 0, 450, 276, 444, 352, 360, 287], [ 0, 0, 0, 276, 444, 432, 576, 205, 567], [ 0, 0, 0, 444, 432, 576, 328, 405, 350], [ 0, 0, 0, 432, 576, 0, 648, 250, 0]], [[ 0, 300, 276, 0, 264, 432, 0, 80, 490], [375, 184, 444, 264, 432, 246, 128, 350, 154], [230, 296, 432, 432, 246, 486, 560, 110, 133], [370, 288, 576, 246, 486, 300, 176, 95, 343], [360, 384, 0, 486, 300, 0, 152, 245, 0]], [[ 0, 176, 432, 0, 96, 420, 0, 435, 518], [220, 288, 246, 96, 420, 132, 696, 370, 546], [360, 164, 486, 420, 132, 114, 592, 390, 462], [205, 324, 300, 132, 114, 294, 624, 330, 343], [405, 200, 0, 114, 294, 0, 528, 245, 0]], [[ 0, 64, 420, 0, 522, 444, 0, 0, 0], [ 80, 280, 132, 522, 444, 468, 0, 0, 0], [350, 88, 114, 444, 468, 396, 0, 0, 0], [110, 76, 294, 468, 396, 294, 0, 0, 0], [ 95, 196, 0, 396, 294, 0, 0, 0, 0]]]) 4] let's verify results. first sliding window on un-padded region a[:3,:3]. let's multiply against m. after multiplication, should same out[1,1,:] -
in [67]: a[:3,:3]*m out[67]: array([[375, 184, 444], [264, 432, 246], [128, 350, 154]]) in [68]: out[1,1,:] out[68]: array([375, 184, 444, 264, 432, 246, 128, 350, 154]) it's worth mentioning here 3d array of sliding windows views array , such efficient on further operations involving -
in [75]: np.may_share_memory(a1,vieww(a1,[3,3])) out[75]: true
Comments
Post a Comment