Sliding Window Cheatsheet

 

Alright, this is something that I am sick of having to figure out over and over again. Sliding window.

Case 1: Stride Length = Window Length

Let us first consider the simplest case: where are trying to pass a window through some data, and your stride length equals the window length. If we were to know a priori the number of times we’d like to iterate through (e.g. 10 iterations), then this is the simplest case. We can simply let it iterate through integers, and ad a factor of the length of the window

window_length = 15

for k in range(10):
    start = k * window_length
    stop = (k+1) * window_length
    print(start, stop)

# Output 
# 0 15
# 15 30
# 30 45
# 45 60
# 60 75
# 75 90
# 90 105
# 105 120
# 120 135
# 135 150

If we however have a finite array with $N$ elements, we need to know the number of segments $n_{frames}$ we will need. With this, we can determine it by simply compute it by dividing the number of elements by the window length and flooring it

\[n_{frames} = \bigg\lfloor \frac{N}{window\_length} \bigg\rfloor\]
data = np.arange(100)
window_length = 16
N = data.shape[0]
n_frames = N // window_length
for k in range(n_frames):
    start = k * window_length
    stop = (k+1) * window_length
    print(start, stop, "\t", len(data[start:stop]))

# Output

#  0 16     [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15]
# 16 32     [16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31]
# 32 48     [32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47]
# 48 64     [48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63]
# 64 80     [64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79]
# 80 96     [80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95]

Case 2: Infinite Data

Let us consider the case we now do not have the window length to be equal to the stride length. Let us also consider that we either know a priori the number of iterations we wish to go through, or we have infinite data. Let $k$ be the iteration number. We now change the start and end indices to

\[\begin{align} start &= k \cdot stride\_length \\ stop &= k \cdot stride\_length + window\_length \end{align}\]
stride_length = 10
window_length = 16

for k in range(10):
    start = k * stride_length
    stop = k * stride_length + window_length
    print(start,stop)

# Output

#  0 16
# 10 26
# 20 36
# 30 46
# 40 56
# 50 66
# 60 76
# 70 86
# 80 96
# 90 106

Case 3: Finite Data

Now, let us consider the case that we have a finite data with differing window lengths and stride lengths. In such case, we first need to determine the number of frames we’ll need. Let $N$ represent the number of data points you possess. This can be computed by

\[n_{frames} = \bigg \lfloor \frac{N - window\_length}{stride\_length} \bigg \rfloor + 1\]

We can the iterate it with the same formulation above, where $k$ represents the iteration number

\[\begin{align} start &= k \cdot stride\_length \\ stop &= k \cdot stride\_length + window\_length \end{align}\]

Thus, its implementation is

stride_length = 4
window_length = 6
data = np.arange(100)
N = data.shape[0]
n_frames = ((N - window_length)  // stride_length) + 1
for k in range(n_frames):
    start = k * stride_length
    stop = k * stride_length + window_length
    print("({:>2}) {:>2} {:>2}".format(k, start,stop), data[start:stop])

# Output

# ( 0)  0 13	 [ 0  1  2  3  4  5  6  7  8  9 10 11 12]
# ( 1)  7 20	 [ 7  8  9 10 11 12 13 14 15 16 17 18 19]
# ( 2) 14 27	 [14 15 16 17 18 19 20 21 22 23 24 25 26]
# ( 3) 21 34	 [21 22 23 24 25 26 27 28 29 30 31 32 33]
# ( 4) 28 41	 [28 29 30 31 32 33 34 35 36 37 38 39 40]
# ( 5) 35 48	 [35 36 37 38 39 40 41 42 43 44 45 46 47]
# ( 6) 42 55	 [42 43 44 45 46 47 48 49 50 51 52 53 54]
# ( 7) 49 62	 [49 50 51 52 53 54 55 56 57 58 59 60 61]
# ( 8) 56 69	 [56 57 58 59 60 61 62 63 64 65 66 67 68]
# ( 9) 63 76	 [63 64 65 66 67 68 69 70 71 72 73 74 75]
# (10) 70 83	 [70 71 72 73 74 75 76 77 78 79 80 81 82]
# (11) 77 90	 [77 78 79 80 81 82 83 84 85 86 87 88 89]
# (12) 84 97	 [84 85 86 87 88 89 90 91 92 93 94 95 96]

Done. Get to work.