Reputation: 2726
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
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