NumPy basics¶

This chapter introduces NumPy, a powerful library for numerical computing in Python. You will learn how to create and manipulate arrays, perform vectorized operations, and explore some basic linear algebra tools.

What is NumPy?¶

NumPy (Numerical Python) provides efficient data structures and operations for working with large numerical datasets. Compared to Python lists, NumPy arrays are more compact, faster, and support advanced operations such as broadcasting and linear algebra.

To use NumPy in your code, you need to import it:

import numpy as np

Creating arrays¶

You can create NumPy arrays from Python lists:

a = np.array([1, 2, 3])
b = np.array([[1, 2], [3, 4]])

Useful functions for creating arrays include:

np.zeros((2, 3))       # array of zeros
np.ones((3,))          # array of ones
np.full((2, 2), 7)     # filled with 7s
np.eye(3)              # identity matrix
np.arange(0, 10, 2)    # evenly spaced values
np.linspace(0, 1, 5)   # linearly spaced values

Array properties¶

Each array has several useful properties:

a.shape     # dimensions
a.ndim      # number of dimensions
a.size      # total number of elements
a.dtype     # data type

Indexing and slicing¶

You can access and modify elements just like Python lists:

x = np.array([[10, 20, 30], [40, 50, 60]])
x[1, 2]       # single element
x[:, 1]       # second column
x[0:2, 1:]    # submatrix

Boolean and fancy indexing:

x[x > 30]         # boolean mask
x[[0, 1], [1, 2]] # access (0,1) and (1,2)

Array operations¶

NumPy supports element-wise operations:

a = np.array([1, 2, 3])
b = np.array([10, 20, 30])

a + b      # element-wise addition
a * b      # element-wise multiplication
a ** 2     # square each element

Functions that operate on entire arrays:

np.sum(a)
np.mean(a)
np.max(a)
np.min(a)
np.std(a)

Broadcasting allows operations on arrays of different shapes:

a = np.array([[1], [2], [3]])
b = np.array([10, 20, 30])
a + b

Reshaping arrays¶

You can change the shape of an array:

a = np.arange(6)
a.reshape((2, 3))
a.flatten()     # 1D copy
a.ravel()       # 1D view (if possible)
a.T             # transpose

Add new axes:

a[:, np.newaxis]
np.expand_dims(a, axis=0)

Linear algebra basics¶

NumPy includes basic linear algebra operations:

A = np.array([[1, 2], [3, 4]])
b = np.array([5, 6])

np.dot(A, b)             # dot product
np.matmul(A, A)          # matrix multiplication
A @ A                    # same as matmul

np.linalg.inv(A)         # inverse
np.linalg.norm(A)        # norm
np.linalg.solve(A, b)    # solve Ax = b

Random number generation¶

NumPy provides a random module for generating random numbers:

np.random.seed(0)        # for reproducibility

np.random.rand(2, 3)     # uniform [0, 1)
np.random.randn(3)       # standard normal
np.random.integers(1, 10, size=(2, 2))  # random integers
np.random.choice([1, 2, 3], size=5)     # random choice

Practical examples¶

Compute Euclidean distance between points¶

a = np.array([1, 2])
b = np.array([4, 6])
distance = np.linalg.norm(a - b)

Normalize each row of a matrix¶

X = np.array([[1, 2], [3, 4]])
row_norms = np.linalg.norm(X, axis=1, keepdims=True)
X_normalized = X / row_norms

Monte Carlo estimate of pi¶

np.random.seed(0)
N = 10000
x = np.random.rand(N)
y = np.random.rand(N)
inside = x**2 + y**2 <= 1
pi_estimate = 4 * np.sum(inside) / N