Home > database >  Is there a numpy built-in to do this?
Is there a numpy built-in to do this?

Time:04-18

while doing BoxBlur exercise from CodeSignal, it asks to split the image matrix into a 3x3 sub-matrix, like this:

[[7,4,0,1],          [[7, 4, 0], [5, 6, 2], [6, 10, 7]] 
 [5,6,2,2],   --->   [[4, 0, 1], [6, 2, 2], [10, 7, 8]] 
 [6,10,7,8],         [[5, 6, 2], [6, 10, 7], [1, 4, 2]] 
 [1,4,2,0]]          [[6, 2, 2], [10, 7, 8], [4, 2, 0]] 

I wrote this following code, where it solves the problem with pure python:

def get_grid(matrix, height, width):
    for i in range(len(matrix) - height   1):
        for j in range(len(matrix) - width   1):
            yield [row[j:j width] for row in matrix[i:i height]

Also I tried something with numpy that produces the same result:

# in this case the matrix come as a numpy.array
def get_grid(matrix, height, width):
    for i in range(len(matrix) - height   1):
        for j in range(len(matrix) - width   1):
            yield matrix[i:i height, j:j width]

I wonder if there is somehow to produce the same results with numpy built-in or a more pythonic way.

CodePudding user response:

Answering this from the suggestions of the comments to get this off the unanswered queue. You can use np.lib.stride_tricks.sliding_window_view to get the "convolution" sliding window values with specified size. In your example

import numpy as np

A = [[7,4,0,1],
     [5,6,2,2],
     [6,10,7,8],
     [1,4,2,0]]

res = np.lib.stride_tricks.sliding_window_view(A, (3,3)).reshape(-1, 3, 3) 

You will need to reshape since the resulting shape would be (2, 2, 3, 3) otherwise.

  • Related