Memory Layout & Strides
Memory layout describes the physical order in which an array's elements are stored, and strides are the byte steps NumPy takes to walk along each axis — together they explain why some operations are fast and others are slow.
Learn Memory Layout & Strides in our free NumPy course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Numpy course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
You'll inspect an array's .flags and .strides , compare C (row-major) and F (column-major) order, see how transpose just swaps strides, and force a contiguous copy with ascontiguousarray .
Under the hood an array is just a flat block of bytes plus a shape. The .flags attribute tells you how that block is organized. A default array is C-contiguous (row-major): each row is laid out end to end. Build one with order="F" and it becomes F-contiguous (column-major) instead.
.strides reports how many bytes to step to advance one index along each axis. For a C-contiguous int64 array of shape (2, 3) the strides are (24, 8) : 8 bytes to the next column, 24 to the next row. Transposing does not move any data — it simply swaps the strides , which is why .T is instant even on huge arrays.
Iterating along the axis whose elements are adjacent in memory is cache-friendly and fast; iterating across the gaps is slow. When a non-contiguous array (like a transpose) is about to feed many operations, make a contiguous copy with np.ascontiguousarray . ravel flattens an array, and its order argument lets you read it out in C or F order.
On a big array, a contiguous copy lets the CPU stream through the data instead of jumping around — that is the whole reason a slow transposed operation often speeds up after ascontiguousarray .
Replace each ___ so the program checks contiguity and flattens an array in column-major order.
Expected output: True then [0 4 1 5 2 6 3 7] . (Answers: flags , order .)
.T only swaps strides, so the result is usually not C-contiguous.
✅ Fix: check .flags , and call np.ascontiguousarray(arr.T) when an op needs contiguous data.
C and F order hold the same numbers; only the byte arrangement differs.
✅ Fix: use order= when you care about memory or flattening direction, not when comparing values.
Start from a C-contiguous array, convert it to Fortran order with np.asfortranarray , and confirm the strides change while the values stay identical.
Lesson complete — memory layout unlocked!
You can now read .flags and .strides , tell C from F order, explain why transpose is free, and force a contiguous copy with ascontiguousarray when speed matters.
🚀 Up next: ufunc Methods — reduce, accumulate, outer, and at on universal functions.
Practice quiz
What does C order (the NumPy default) mean for a 2D array?
- Row-major: rows are stored end to end
- Column-major: columns first
- Random order
- Compressed order
Answer: Row-major: rows are stored end to end. C order is row-major, storing one full row after another.
What does F order mean?
- Float order
- Column-major (like Fortran)
- Fast order
- Filtered order
Answer: Column-major (like Fortran). F order is column-major, storing one full column after another.
What do an array's .strides report?
- The element count
- The dtype name
- The bytes to step to advance one index along each axis
- The number of dimensions
Answer: The bytes to step to advance one index along each axis. .strides give the byte steps to move one index along each axis.
What is a.flags['C_CONTIGUOUS'] for a default np.arange(12).reshape(3,4)?
- False
- None
- An error
- True
Answer: True. A default array is C-contiguous, so the flag is True.
What happens to the strides when you transpose with .T?
- They are swapped, with no data copied
- They double
- They reset to (8, 8)
- The data is reordered in memory
Answer: They are swapped, with no data copied. Transpose just swaps the strides over the same bytes; no data moves.
After c.T on a C-contiguous array c, the result is usually:
- Still C-contiguous
- F-contiguous, not C-contiguous
- Neither layout
- A scalar
Answer: F-contiguous, not C-contiguous. Transposing a C-contiguous array makes it F-contiguous, not C-contiguous.
What does np.arange(6).reshape(2,3).ravel(order='F') return?
Column-major flattening reads down columns: [0 3 1 4 2 5].
Which function forces a fresh C-contiguous copy of an array?
- np.ascontiguousarray
- np.ravel
- np.reshape
- np.transpose
Answer: np.ascontiguousarray. np.ascontiguousarray makes a contiguous copy the CPU can stream through.
For a C-contiguous int64 array of shape (2, 3), what are the strides?
- (8, 8)
- (24, 8)
- (3, 2)
- (8, 24)
Answer: (24, 8). 8 bytes to the next column and 24 to the next row, so (24, 8).
Do C order and F order of the same array hold different values?
- Yes, the values change
- Only for floats
- No, same values, only the byte arrangement differs
- Only for 3D arrays
Answer: No, same values, only the byte arrangement differs. Layout changes only the physical arrangement, never the values.