An array stride is the signed number of bytes the address moves when an index increases by one along an axis. A NumPy array has one stride per axis. In a risk pipeline, you can transpose a scenario-by-asset table without copying its values, but a later routine may still need to repack it. Shape tells you which indices are valid. Strides tell you how those indices reach memory. NumPy: ndarray.strides
Two ways to reach byte 40
Take a toy scenario table
a with two rows and three columns, stored in C order. Each int64 element occupies 8 bytes. Advancing one column moves 8 bytes. Advancing one row at the same column moves past three elements, or 24 bytes. With zero-based indices and strides , the byte offset from the start of this array is .The transpose
a.T swaps the axes. Its shape changes from (2, 3) to (3, 2) and its strides from (24, 8) to (8, 24). The starting address is shared, so a[1, 2] and a.T[2, 1] reach the same bytes through different index calculations. Writing through this transposed view changes the original value too. NumPy: transpose, NumPy: copies and viewsThe upper grids show logical index order. The lower strip shows the six values in physical memory order and the starting byte of each.
Contiguity and the next operation
Both arrays in the example use contiguous memory. The original is C-contiguous, so the last axis runs fastest in memory. The transpose is Fortran-contiguous, so the first axis runs fastest. Slicing can also yield a view that skips elements and has neither flag. Read
flags.c_contiguous and flags.f_contiguous to check the layout. An axis of length one may have an arbitrary stride because its index never advances. NumPy: ndarray memory layoutA routine that accepts the transpose's strides can read the shared buffer directly. A routine that requires C order needs a C-order copy of this transpose, which
np.ascontiguousarray can make explicitly. The copy preserves the transposed shape and values and allocates a separate buffer. NumPy: ascontiguousarrayimport numpy as np
a = np.array([[4, 7, 2], [3, 8, 6]], dtype=np.int64, order="C")
t = a.T
print(a.strides, t.strides)
# (24, 8) (8, 24)
print(t.flags.c_contiguous, t.flags.f_contiguous, np.shares_memory(a, t))
# False True True
packed = np.ascontiguousarray(t)
print(packed.strides, np.shares_memory(t, packed))
# (16, 8) FalseFor performance, follow the routine's actual inner loop. Reading adjacent elements can make better use of the cache than taking large jumps, but an iterator can choose memory order even when the logical rows run across it. NumPy's
nditer does so by default for this transpose. Repacking incurs a copy up front, so its cost belongs in any timing comparison. NumPy: iterating over arraysSources
- NumPy Developers, NumPy v2.5 Manual. Strides, array layout, transpose, copies and views, C-order conversion, and iteration order.