13

Lets say I have an array:

>>> arr = np.array(range(9)).reshape(3, 3)
>>> arr
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

I would like to create a function f(arr, shape=(2, 2)) that takes the array and a shape, and splits the array into chunks of the given shape without padding. Thus, by overlapping certain parts if necessary. For example:

>>> f(arr, shape=(2, 2))
array([[[[0, 1],
         [3, 4]],

        [[1, 2],
         [4, 5]]],

       [[[3, 4],
         [6, 7]],

        [[4, 5],
         [7, 8]]]])

I managed to creates to output above with np.lib.stride_tricks.as_strided(arr, shape=(2, 2, 2, 2), strides=(24, 8, 24, 8)). But I don't know how to generalize this for to all arrays and all chunk sizes.

Preferably, for 3D arrays.

If no overlap is necessary, it should avoid that. Another example:

>>> arr = np.array(range(16).reshape(4,4)
>>> arr
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])
>>> f(arr, shape=(2,2))
array([[[[0, 1],
         [4, 5]],

        [[2, 3],
         [6, 7]]],

       [[[8, 9],
         [12, 13]],

        [[10, 11],
         [14, 15]]]])

skimage.util.view_as_blocks comes close, but requires that the array and block shape are compatible.

1 Answer 1

11

There's a builtin in scikit-image as view_as_windows for doing exactly that -

from skimage.util.shape import view_as_windows

view_as_windows(arr, (2,2))

Sample run -

In [40]: arr
Out[40]: 
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

In [41]: view_as_windows(arr, (2,2))
Out[41]: 
array([[[[0, 1],
         [3, 4]],

        [[1, 2],
         [4, 5]]],


       [[[3, 4],
         [6, 7]],

        [[4, 5],
         [7, 8]]]])

For the second part, use its cousin from the same family/module view_as_blocks -

from skimage.util.shape import view_as_blocks

view_as_blocks(arr, (2,2))
Sign up to request clarification or add additional context in comments.

2 Comments

I should have been more clear, I only want them overlapping if necessary. I will provide another example. Thanks.
@Divakar say I had an array A with A.shape = (n,m,n), and I wanted to pull the 26 elements surrounding A[i,j,k] (i.e. A[i+1,j,k], A[i-1,j+1,k-1] etc.) I suppose view_as_blocks(A,(3,3,3)) would be close to what I want-- but how would I fix A[i,j,k] to be the center element of the block instead of the corner element? I hope this makes sense. Would the array I seek just be view_as_blocks(A,(3,3,3))[i+1,j+1,k+1]?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.