kevinkayaks
kevinkayaks

Reputation: 2726

Viewing cells of a grid in sliding windows with periodic boundaries

Consider a 2D array

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

I would like to construct a function f(i,j) which pulls a 3x3 block from elements surrounding A[i,j] with periodic boundary conditions.

For example a non-boundary element would be

>>> f(1,1)
array([[ 0,  1,  2],
       [ 4,  5,  6],
       [ 8,  9, 10]])

and a boundary element would be

>>> f(0,0)
array([[15, 12, 13],
       [ 3,  0,  1],
       [ 7,  4,  5]])

view_as_windows comes close but does not wrap around periodic boundaries.

>>> from skimage.util.shape import view_as_windows
>>> view_as_windows(A,(3,3))
array([[[[ 0,  1,  2],
     [ 4,  5,  6],
     [ 8,  9, 10]],

    [[ 1,  2,  3],
     [ 5,  6,  7],
     [ 9, 10, 11]]],


   [[[ 4,  5,  6],
     [ 8,  9, 10],
     [12, 13, 14]],

    [[ 5,  6,  7],
     [ 9, 10, 11],
     [13, 14, 15]]]])

In this case view_as_windows(A)[0,0] == f(1,1) but f(0,0) is not in view_as_windows(A). I need a view_as_windows(A) type array which has the same number of elements as A, where each element has shape (3,3)

Upvotes: 1

Views: 319

Answers (1)

Divakar
Divakar

Reputation: 221614

Simply pad with wrapping functionality using np.pad and then use Scikit's view_as_windows -

from skimage.util.shape import view_as_windows

Apad = np.pad(A,1,'wrap')
out = view_as_windows(Apad,(3,3))

Sample run -

In [65]: A
Out[65]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])

In [66]: Apad = np.pad(A,1,'wrap')

In [67]: out = view_as_windows(Apad,(3,3))

In [68]: out[0,0]
Out[68]: 
array([[15, 12, 13],
       [ 3,  0,  1],
       [ 7,  4,  5]])

In [69]: out[1,1]
Out[69]: 
array([[ 0,  1,  2],
       [ 4,  5,  6],
       [ 8,  9, 10]])

Upvotes: 1

Related Questions