Created
June 11, 2016 18:45
-
-
Save nils-werner/9d321441006b112a4b116a8387c2280c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def sliding_window(data, size, stepsize=1, padded=False, axis=-1, copy=True): | |
""" | |
Calculate a sliding window over a signal | |
Parameters | |
---------- | |
data : numpy array | |
The array to be slided over. | |
size : int | |
The sliding window size | |
stepsize : int | |
The sliding window stepsize. Defaults to 1. | |
axis : int | |
The axis to slide over. Defaults to the last axis. | |
copy : bool | |
Return strided array as copy to avoid sideffects when manipulating the | |
output array. | |
Returns | |
------- | |
data : numpy array | |
A matrix where row in last dimension consists of one instance | |
of the sliding window. | |
Notes | |
----- | |
- Be wary of setting `copy` to `False` as undesired sideffects with the | |
output values may occurr. | |
Examples | |
-------- | |
>>> a = numpy.array([1, 2, 3, 4, 5]) | |
>>> sliding_window(a, size=3) | |
array([[1, 2, 3], | |
[2, 3, 4], | |
[3, 4, 5]]) | |
>>> sliding_window(a, size=3, stepsize=2) | |
array([[1, 2, 3], | |
[3, 4, 5]]) | |
See Also | |
-------- | |
pieces : Calculate number of pieces available by sliding | |
""" | |
if axis >= data.ndim: | |
raise ValueError( | |
"Axis value out of range" | |
) | |
if stepsize < 1: | |
raise ValueError( | |
"Stepsize may not be zero or negative" | |
) | |
if size > data.shape[axis]: | |
raise ValueError( | |
"Sliding window size may not exceed size of selected axis" | |
) | |
shape = list(data.shape) | |
shape[axis] = numpy.floor(data.shape[axis] / stepsize - size / stepsize + 1).astype(int) | |
shape.append(size) | |
strides = list(data.strides) | |
strides[axis] *= stepsize | |
strides.append(data.strides[axis]) | |
strided = numpy.lib.stride_tricks.as_strided( | |
data, shape=shape, strides=strides | |
) | |
if copy: | |
return strided.copy() | |
else: | |
return strided |
Hi!
I wanted to report that there is a problem with 2D input data that one can reproduce as:
>>> x = np.arange(30).reshape(3, -1)
>>> x
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29]])
>>> sliding_window(x, 3, 2)
array([[[ 0, 1, 2],
[ 2, 3, 4],
[ 4, 5, 6],
[ 6, 7, 8]],
[[10, 11, 12],
[12, 13, 14],
[14, 15, 16],
[16, 17, 18]],
[[20, 21, 22],
[22, 23, 24],
[24, 25, 26],
[26, 27, 28]]])
which is particularly weird because the epochs have more rows than the input. The correct output should be, in my opinion:
>>> epoch(x, 3, 2)
array([[[ 0, 1, 2],
[10, 11, 12],
[20, 21, 22]],
[[ 2, 3, 4],
[12, 13, 14],
[22, 23, 24]],
[[ 4, 5, 6],
[14, 15, 16],
[24, 25, 26]],
[[ 6, 7, 8],
[16, 17, 18],
[26, 27, 28]]])
Which I generated with: https://gist.github.com/dojeda/2250ad463a925a38d7179ec913167ebc
but I am not 100% sure it works on all other cases as well.
Nowadays I recommend using skimage.util.view_as_windows()
instead:
skimage.util.view_as_windows(x, (3, 3), step=2)
# array([[[[ 0, 1, 2],
# [10, 11, 12],
# [20, 21, 22]],
#
# [[ 2, 3, 4],
# [12, 13, 14],
# [22, 23, 24]],
#
# [[ 4, 5, 6],
# [14, 15, 16],
# [24, 25, 26]],
#
# [[ 6, 7, 8],
# [16, 17, 18],
# [26, 27, 28]]]])
Nice, I didn't known sklearn had this util function.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Tnx for sharing, it helped me a lot!