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

Popular posts from this blog

sql server - Cannot query correctly (MSSQL - PHP - JSON) -

php - trouble displaying mysqli database results in correct order -

C++ Linked List -