NumPy Cheatsheet
Arrays
Use this NumPy reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
What is an ndarray
NumPy's core object is the n-dimensional array (numpy.ndarray). Every element shares the same dtype; axes are called dimensions or axes; the size along each axis is the shape.
import numpy as np a = np.array([1, 2, 3]) # 1-D, shape (3,) b = np.array([[1, 2], [3, 4]]) # 2-D, shape (2, 2) c = np.array([[[1]], [[2]]]) # 3-D, shape (2, 1, 1)
Key Attributes
| Attribute | Description | Example |
|---|---|---|
a.ndim | number of axes | 1, 2, 3 |
a.shape | tuple of axis lengths | (3,), (2, 2) |
a.size | total number of elements | 6 |
a.dtype | element data type | dtype('float64') |
a.itemsize | bytes per element | 8 |
a.nbytes | total bytes (size * itemsize) | 48 |
a.strides | bytes to step per axis | (8,) |
a.T | transposed view | ndarray |
a.flat | flat iterator over elements | flatiter |
a.data | buffer object (rarely used) | memoryview |
a.flags | memory layout info | C_CONTIGUOUS, etc. |
a = np.array([[1.0, 2.0], [3.0, 4.0]]) print(a.shape) # (2, 2) print(a.dtype) # float64 print(a.nbytes) # 32 print(a.strides) # (16, 8)
Data Types (dtype)
Common dtypes
| dtype | Alias | Description |
|---|---|---|
np.bool_ | bool | Boolean |
np.int8 / int16 / int32 / int64 | — | Signed integers |
np.uint8 / uint16 / uint32 / uint64 | — | Unsigned integers |
np.float16 / float32 / float64 | np.half / single / double | Floats |
np.complex64 / complex128 | — | Complex numbers |
np.str_ | — | Fixed-width Unicode (np.unicode_ removed in NumPy 2.0) |
np.bytes_ | — | Fixed-width bytes |
np.object_ | — | Arbitrary Python objects |
Specifying and casting
a = np.array([1, 2, 3], dtype=np.float32) b = a.astype(np.int64) # cast; always returns a copy c = a.astype("complex128") # string alias also works d = np.array([1.9, 2.7]).astype(int) # truncates toward zero → [1, 2]
Gotcha: integer overflow wraps silently.
np.int8(127) + 1 == -128.
Structured / record arrays
dt = np.dtype([("name", "U10"), ("age", "i4"), ("score", "f8")]) rec = np.array([("Alice", 30, 9.5), ("Bob", 25, 8.0)], dtype=dt) rec["name"] # array(['Alice', 'Bob'], dtype='<U10') rec["score"] # array([9.5, 8. ])
Memory Layout
| Flag | Meaning |
|---|---|
C-contiguous (C) | Row-major; last index changes fastest (default) |
Fortran-contiguous (F) | Column-major; first index changes fastest |
a = np.ones((3, 4), order="C") # C-contiguous b = np.ones((3, 4), order="F") # Fortran-contiguous np.ascontiguousarray(b) # return C-contiguous copy/view np.asfortranarray(a) # return F-contiguous copy/view a.flags["C_CONTIGUOUS"] # True
Views vs Copies
a = np.array([1, 2, 3, 4]) b = a[1:3] # VIEW — shares memory b[0] = 99 # also changes a[1] c = a[1:3].copy() # explicit COPY — independent # Check np.shares_memory(a, b) # True np.shares_memory(a, c) # False b.base is a # True (b is a view of a) c.base is None # True (c owns its data)
Gotcha: fancy indexing (integer arrays, boolean masks) always returns a copy, not a view. Basic slicing returns a view.
Printing and Representation
np.set_printoptions(precision=3, suppress=True, linewidth=120) np.set_printoptions(threshold=np.inf) # print full array, never "..." np.get_printoptions() # inspect current settings # Context manager (NumPy ≥ 1.15) with np.printoptions(precision=2): print(np.pi * np.ones(5))