For everything to work as quickly as possible, yours would be to calculate everything with numpy operations, without using explicit loops.Depending on whether or not you want to remove the missing elements to make the dimensions a multiple of the BLOCK_SIZES, you can add zeros (np.pador remove the remaining elements (slicing).With a.reshape(r_, nrows, c_, ncols) the matrix can be converted into a set of submatrics. np.count_nonzero you can count how many elements are not zero. Axis 1 and 3 form submatrics. Turning the result into Bool converts every zero into False and the other numbers in True. Although not recommended, you can convert those into zeros and one with astype(np.int).Example code:import numpy as np
def create_mask(a, nrows, ncols, pad_with_zeros=False):
r, c = a.shape
if pad_with_zeros:
r_, c_ = int(np.ceil(r / nrows)), int(np.ceil(c / ncols))
a = np.pad(a, ((0, r - r_ * nrows), (0, c - c_ * ncols))) # añadir ceros para que cada submatriz sea igual
else:
r_, c_ = r // nrows, c // ncols
a = a[:r_ * nrows, :c_ * ncols] # quitar los últimos elementos para que cada submatriz sea igual
a = a.reshape(r_, nrows, c_, ncols)
return np.count_nonzero(a, axis=(1,3)).astype(np.bool).astype(np.int)
N = 8
cnt = 10
a = np.zeros((N, N), dtype=np.int)
ind = np.random.randint(0, N-1, cnt*2).reshape(-1,2)
a[ind[:,0], ind[:,1] ] = np.arange(1, cnt+1, dtype=np.int)
print(a)
print(create_mask(a, 2, 2))
Example of result:[[ 5 0 0 0 10 0 0 0]
[ 9 0 0 2 0 6 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]
[ 8 0 7 4 0 0 3 0]
[ 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]]
[[1 1 1 0]
[0 0 0 0]
[1 1 0 1]
[0 0 0 0]]
To calculate directly matrix B, the code would be a little different:import numpy as np
def comprime_matrix(a, nrows, ncols, pad_with_zeros=False):
r, c = a.shape
if pad_with_zeros:
r_, c_ = int(np.ceil(r / nrows)), int(np.ceil(c / ncols))
a = np.pad(a, ((0, r - r_ * nrows), (0, c - c_ * ncols))) # añadir ceros para que cada submatriz sea igual
else:
r_, c_ = r // nrows, c // ncols
a = a[:r_ * nrows, :c_ * ncols] # quitar los últimos elementos para que cada submatriz sea igual
a = np.vstack(np.swapaxes(a.reshape(r_, nrows, c_, ncols), 1, 2))
return a[np.count_nonzero(a, axis=(1, 2)).astype(np.bool)].swapaxes(0, 1).reshape(2, -1)
N = 8
cnt = 10
a = np.zeros((N, N), dtype=np.int)
ind = np.random.randint(0, N-1, cnt*2).reshape(-1,2)
a[ind[:,0], ind[:,1] ] = np.arange(1, cnt+1, dtype=np.int)
print(a)
print(comprime_matrix(a, 2, 2))
Example of result:[[ 0 0 0 10 0 0 0 0]
[ 2 0 0 0 0 1 0 0]
[ 4 0 0 0 3 0 7 0]
[ 0 0 0 0 8 0 0 0]
[ 0 0 0 0 0 0 9 0]
[ 0 0 0 0 0 0 0 0]
[ 0 6 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0]]
[[ 0 0 0 10 0 0 4 0 3 0 7 0 9 0 0 6]
[ 2 0 0 0 0 1 0 0 8 0 0 0 0 0 0 0]]