Reputation: 141
I would like to split an array into equally long intersecting subarrays (last element of previous array coincides with first element of the next array and with periodic boundary conditions).
E.g.
myarray = np.arange(18)
output:
splitarray = [[0,1,2,3,4],[4,5,6,7,8],[8,9,10,11,12],[12,13,14,15,16],[16,17,0,1,2]]
(the 3 last elements of the last subarray correspond to the first 3 elements of the initial array!)
What is the most efficient way to implement this in Python?
Upvotes: 1
Views: 294
Reputation: 114440
The pure-numpy equivalent of ski.util.view_as_windows
is np.lib.stride_tricks.as_strided
:
arr = np.arange(18)
w = 5
if arr.size == 1:
h = 1
x = 4
else:
h = np.ceil((arr.size - 1) / (w - 1)).astype(int)
x = (1 - arr.size) % (w - 1)
view = np.lib.stride_tricks.as_strided(np.r_[arr, arr[:x]], shape=(h, w), strides=((w - 1) * arr.strides[0], arr.strides[0]))
The result is:
>>> view
array([[ 0, 1, 2, 3, 4],
[ 4, 5, 6, 7, 8],
[ 8, 9, 10, 11, 12],
[12, 13, 14, 15, 16],
[16, 17, 0, 1, 2]])
The overlapping elements are actually referring to the same memory, so use this view very very carefully.
Upvotes: 3
Reputation: 88276
You could use skimage's view_as_windows
to take overlapping views of the input array, and concatenate the first w-1
items accordingly for the last window:
from skimage.util import view_as_windows
def view_strided_with_roll(a, w):
a = np.r_[a, a[:w-1]]
return view_as_windows(a, window_shape=w, step=w-1)
myarray = np.arange(18)
view_strided_with_roll(myarray, 5)
array([[ 0, 1, 2, 3, 4],
[ 4, 5, 6, 7, 8],
[ 8, 9, 10, 11, 12],
[12, 13, 14, 15, 16],
[16, 17, 0, 1, 2]])
Upvotes: 2