NumPy Cheatsheet
Arrays
Use this NumPy reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
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))