Home > Mobile >  Sum in square inside np.array
Sum in square inside np.array

Time:10-05

I have variable:

Q = np.asarray([
   [0.20, 0.  , 0.3 , 0.1 ],
   [0.10, 0.  , 0.2 , 0.  ],
   [0.05, 0.  , 0.  , 0.  ],
   [0.  , 0.  , 0.  , 0.05],
], dtype=float)

And I want for each element to find a sum of itself and upper, upper-left, left elements.
If there is no left or upper-left or upper elements we need to make the sum of what we have.
In return I need to get J with these sums.
For example:J[3][3] = Q[3][3] Q[3][2] Q[2][2] Q[2][3]
J[0][1] = Q[0][1] Q[0][0]


Can I do this via numpy functions only? I want it to be very fast, so NO cycles.
Do you have any ideas?

UPD: The resulting array should be the same size as Q

J = np.array([
   [0.2 , 0.2 , 0.3 , 0.4 ],
   [0.3 , 0.3 , 0.5  , 0.6 ],
   [0.15, 0.15, 0.2 , 0.2 ],
   [0.05 , 0.05 , 0.  , 0.05 ],
])

CodePudding user response:

To sum up all elements in a sliding 2x2 window, you can use scipy.signal.convolve2d to do a 2d-convolution of your array with a unit kernel of shape (2, 2):

import numpy as np
from scipy.signal import convolve2d

kernel = np.ones((2, 2))  

Q = np.asarray([
   [0.20, 0.  , 0.3 , 0.1 ],
   [0.10, 0.  , 0.2 , 0.  ],
   [0.05, 0.  , 0.  , 0.  ],
   [0.  , 0.  , 0.  , 0.05],
], dtype=float)

result = convolve2d(Q, kernel, 'valid')
# array([[ 0.3 ,  0.5 ,  0.6 ],
#        [ 0.15,  0.2 ,  0.2 ],
#        [ 0.05,  0.  ,  0.05]])

CodePudding user response:

Just for info, as @JanChristoph's answer is much shorter and more elegant, here it the way to implement it using numpy only:

sub_shape = (2, 2)
view_shape = tuple(np.subtract(Q.shape, sub_shape)   1)   sub_shape
strides = Q.strides   Q.strides

sub_matrices = np.lib.stride_tricks.as_strided(Q, view_shape, strides)

sub_matrices.sum(axis=(2,3))

output:

array([[0.3 , 0.5 , 0.6 ],
       [0.15, 0.2 , 0.2 ],
       [0.05, 0.  , 0.05]])
  • Related