
NumPy for Absolute Beginners: Arrays, Operations & a Handy Cheat Sheet
Prerequisite: You can run a Python script and know what a list is. That’s it. By the end, you'll think in arrays, not loops.
1 What is NumPy and why use it?
NumPy (Numerical Python) is the foundation of scientific computing in Python. It provides:
- Fast, memory-efficient arrays (
ndarray
) in place of Python lists. - Element-wise arithmetic and vectorised operations that run in optimized C loops.
- Building block for libraries like Pandas, SciPy, scikit-learn, and many others.
Analogy: Think of a Python list as a row of lockers you open one by one. An
ndarray
is like pressing one button to open them all at once.
Install with:
pip install numpy
# or, if you use Anaconda:
conda install numpy
2 Creating your first array: from lists to matrices
A NumPy array, or ndarray, can hold data in 1, 2, or more dimensions. You build one from Python lists:
import numpy as np
# 1D array (vector)
vector = np.array([10, 20, 30])
# 2D array (matrix)
matrix = np.array([[1, 2, 3], [4, 5, 6]])
# 3D array (e.g. a stack of matrices)
stack = np.array([
[[1,2],[3,4]],
[[5,6],[7,8]]
])
print(vector.shape) # (3,)
print(matrix.shape) # (2, 3)
print(stack.shape) # (2, 2, 2)
- 1D arrays behave like lists but much faster for arithmetic.
- 2D arrays let you represent tables, images, grids.
- Higher dimensions power video data, scientific tensors, and beyond.
3 Quick ways to build common arrays
NumPy has helper functions to avoid typing long lists:
np.zeros((3, 4)) # 3×4 array filled with 0.0s
np.ones(5) # length-5 array of 1.0s
np.full((2, 2), 7) # 2×2 array filled with 7s
np.arange(0, 10, 2) # [0, 2, 4, 6, 8]
np.linspace(0, 1, 5) # [0., 0.25, 0.5, 0.75, 1.]
4 Inspecting an array: shape, size, and data type
A = np.array([[3, 6, 9], [2, 4, 8]], dtype=np.int64)
A.shape # (2, 3): 2 rows, 3 columns
A.ndim # 2: number of dimensions
A.size # 6: total elements
A.dtype # dtype('int64'): data type of elements
You can convert types:
A_float = A.astype(float) # now each entry is a float
5 Indexing and slicing: grab parts of your data
Arrays behave like nested lists:
# Given matrix:
# [[3, 6, 9],
# [2, 4, 8]]
row0 = A[0] # first row → array([3, 6, 9])
elem = A[1, 2] # second row, third column → 8
Slice to get subarrays:
A[:, 1:] # all rows, columns from index 1 → [[6, 9],[4, 8]]
col = A[:, 0] # first column → array([3, 2])
Boolean masks let you filter in one line:
mask = A % 2 == 0 # True for even numbers
evens = A[mask] # array([6, 2, 4, 8])
Note: Slicing returns a view, not a copy. Modifying it will change the original array. Use
copy()
to avoid this.
6 Arithmetic made simple: vectorised operations
With arrays, you write math as if you had whole lists:
x = np.array([1, 2, 3])
y = np.array([10, 20, 30])
x + y # array([11, 22, 33])
x * 2 # array([2, 4, 6])
np.sin(x) # sine of each element
No loops needed—NumPy handles the underlying C magic.
7 Broadcasting: mixing shapes intelligently
Broadcasting lets arrays of different shapes work together:
M = np.array([[0, 1, 2], [3, 4, 5]]) # shape (2,3)
b = np.array([10, 20, 30]) # shape (3,)
M + b # adds b to each row of M, result shape (2,3)
Rules:
- Compare shapes from right to left.
- Dimensions must match or be 1.
- NumPy stretches the 1-sized dimension to match.
Example: adding a column vector of shape
(2,1)
toM
also works.
8 Reshaping, stacking, and splitting arrays
Change the shape without copying data:
A = np.arange(6) # [0,1,2,3,4,5]
B = A.reshape(2, 3) # [[0,1,2],[3,4,5]]
Stack arrays:
row1 = np.array([1,2,3])
row2 = np.array([4,5,6])
stacked = np.vstack([row1, row2]) # shape (2,3)
Split arrays:
left, right = np.split(A, 2) # two halves: [0,1,2] and [3,4,5]
9 Aggregations & basic stats
Summaries across dimensions:
M = np.array([[1, 2, 3], [4, 5, 6]])
M.sum() # 21 total
M.sum(axis=0) # column sums → [5,7,9]
M.mean(axis=1) # row means → [2.,5.]
M.std(axis=None) # std over all elements
Tip: Always specify
axis=
to control whether you collapse rows (axis=1) or columns (axis=0).
10 Random numbers with the new Generator
Use the recommended default_rng
API:
from numpy.random import default_rng
rng = default_rng(seed=123)
rng.integers(0, 10, size=5) # random ints [0,10)
rng.random((2,3)) # floats in [0,1)
This gives reproducible results and better parallel safety.
11 Linear algebra & dot products
from numpy.linalg import inv, eig
A = np.array([[2., 1.], [1., 2.]])
# Inverse:
A_inv = inv(A)
# Matrix multiply:
I = A @ A_inv
# Dot product for vectors:
u = np.array([1,2,3])
np.dot(u, u) # 14
Remember:
*
is element-wise; use@
ordot
for matrix multiplication.
12 Gotchas & pro tips
- Views vs copies: slicing gives a view. Use
.copy()
to get an independent array. - Be explicit with dtype:
np.array([1,2], dtype=float)
ensures floats. - Avoid Python loops: use vectorised operations instead for speed.
- Watch memory layout:
.T
is a view transpose—no data move. - Chaining operations: writing
A += 1
modifiesA
in place.
13 NumPy Cheat Sheet 📄
Action | Example |
---|---|
Import | import numpy as np |
Create array | np.array([1,2,3]) or np.array([[1,2],[3,4]]) |
Zeros / ones | np.zeros((m,n)) , np.ones(shape) |
Ranges | np.arange(start, stop, step) , np.linspace(start, stop, num) |
Random | rng = np.random.default_rng(0) rng.integers(0,10,size) rng.random(shape) |
Reshape | a.reshape(new_shape) |
Stack | np.vstack([a,b]) , np.hstack([a,b]) |
Split | np.split(a, indices_or_sections) |
Math ops | a + b , a * b , np.sqrt(a) |
Matrix mult | a @ b or np.dot(a, b) |
Aggregates | a.sum(axis) , a.mean(axis) , a.std(axis) |
Indexing | a[0] , a[:,1] , a[mask] |
Copy array | b = a.copy() |
Keep this at arm’s reach as you build your first NumPy-powered scripts.
14 What’s next?
- Broadcasting deep dive – master tricky shape interactions.
- Vectorised simulations – run Monte Carlo experiments without loops.
- Under the hood – explore strides, memory layout, and performance tuning.
Happy array-ing! Your future self, running scientific code at C speed, thanks you for learning NumPy now.