Stride Tricks¶
Strides control how NumPy traverses memory to access array elements.
Stride Fundamentals¶
A stride is the number of bytes between consecutive elements along an axis.
1. Definition¶
import numpy as np
def main():
x = np.arange(12).reshape(3, 4)
print(f"{x.strides = }")
print(f"{x.dtype.itemsize = }")
if __name__ == "__main__":
main()
Output:
x.strides = (32, 8)
x.dtype.itemsize = 8
2. Interpretation¶
32bytes to move to the next row (4 elements × 8 bytes)8bytes to move to the next column (1 element × 8 bytes)
3. Memory Layout¶
Strides define how logical indices map to physical memory addresses.
Viewing Strides¶
Different array operations produce different strides.
1. 1D Array Strides¶
import numpy as np
def main():
x = np.arange(10)
print(f"{x.shape = }")
print(f"{x.strides = }")
if __name__ == "__main__":
main()
Output:
x.shape = (10,)
x.strides = (8,)
2. Transposed Strides¶
import numpy as np
def main():
x = np.arange(12).reshape(3, 4)
y = x.T
print(f"{x.strides = }")
print(f"{y.strides = }")
if __name__ == "__main__":
main()
Output:
x.strides = (32, 8)
y.strides = (8, 32)
3. Stride Swap¶
Transpose swaps strides without copying data.
Sliding Windows¶
Create overlapping views efficiently using stride tricks.
1. Basic Window View¶
import numpy as np
from numpy.lib.stride_tricks import sliding_window_view
def main():
arr = np.arange(10)
windowed = sliding_window_view(arr, window_shape=3)
print(windowed)
if __name__ == "__main__":
main()
Output:
[[0 1 2]
[1 2 3]
[2 3 4]
[3 4 5]
[4 5 6]
[5 6 7]
[6 7 8]
[7 8 9]]
2. No Data Copy¶
Each row is a view into the original array, not a copy.
3. Memory Efficient¶
Only stores original data; windows share memory.
Time Series Use¶
Sliding windows are essential for rolling computations.
1. Rolling Mean¶
import numpy as np
from numpy.lib.stride_tricks import sliding_window_view
def main():
data = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
windows = sliding_window_view(data, window_shape=3)
rolling_mean = windows.mean(axis=1)
print(f"{rolling_mean = }")
if __name__ == "__main__":
main()
Output:
rolling_mean = array([2., 3., 4., 5., 6., 7., 8., 9.])
2. Rolling Std¶
import numpy as np
from numpy.lib.stride_tricks import sliding_window_view
def main():
data = np.arange(10, dtype=float)
windows = sliding_window_view(data, window_shape=3)
rolling_std = windows.std(axis=1)
print(f"{rolling_std = }")
if __name__ == "__main__":
main()
3. Signal Processing¶
Sliding windows enable convolution, filtering, and feature extraction.
2D Sliding Windows¶
Apply sliding windows to matrices and images.
1. 2D Window Example¶
import numpy as np
from numpy.lib.stride_tricks import sliding_window_view
def main():
arr = np.arange(16).reshape(4, 4)
print("Original:")
print(arr)
windows = sliding_window_view(arr, window_shape=(2, 2))
print(f"\nWindow shape: {windows.shape}")
if __name__ == "__main__":
main()
Output:
Original:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
Window shape: (3, 3, 2, 2)
2. Image Patches¶
Extract overlapping patches for image processing or neural networks.
Important Caveats¶
Stride manipulation requires careful handling.
1. Aliasing Risk¶
Multiple views share memory; modifying one affects others.
2. Read-Only Views¶
sliding_window_view returns read-only views by default for safety.
3. Undefined Behavior¶
Low-level stride manipulation via as_strided can cause segmentation faults if misused.
Best Practices¶
Guidelines for safe stride manipulation.
1. Use High-Level API¶
Prefer sliding_window_view over manual as_strided.
2. Copy When Needed¶
If you must modify window data, copy first.
3. Validate Shapes¶
Always verify output shapes match expectations.