1

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)

kevinkayaks
  • 2,636
  • 1
  • 14
  • 30
  • 4
    did u look at http://stackoverflow.com/questions/4148292/how-do-i-select-a-window-from-a-numpy-array-with-periodic-boundary-conditions? – plasmon360 May 03 '17 at 23:40
  • Thank you that's very helpful ! – kevinkayaks May 04 '17 at 01:20
  • 1
    For efficient one use views - http://stackoverflow.com/questions/42831022 – Divakar May 04 '17 at 08:00
  • @Divakar this is not a solution because view_as_windows does not account for periodic boundary conditions – kevinkayaks May 05 '17 at 22:58
  • 1
    So, you are saying func `sub_A` would produce lesser elements for boundary elements from `A`? – Divakar May 05 '17 at 23:10
  • I edited for more explanation-- I need to create a larger array as necessary containing A as blocks in order to draw 3x3 arrays which wrap around the boundaries of A. The boundary elements should be the same shape as all other elements – kevinkayaks May 05 '17 at 23:14

1 Answers1

1

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]])
Divakar
  • 218,885
  • 19
  • 262
  • 358