Numerical Computing with NumPy

Authors

Louis Moresi

Andrew Valentine

NoteSummary

NumPy provides efficient array data structures and mathematical operations for scientific computing. In this section we’ll explore how NumPy arrays work, how to manipulate them efficiently, and why they’re fundamental to scientific Python.

Why NumPy?

When we looked at Python data structures, the only way to work with arrays of values (matrices, vectors, etc.) was through lists and lists of lists. This approach is:

  • Slow - Python lists aren’t optimized for numerical operations
  • Inefficient - Looping over elements wastes time and memory
  • Verbose - Simple operations require lots of code

NumPy solves these problems by providing fast,contiguous array storage and vectorized operations.

Creating Arrays

The fundamental NumPy data type is the ndarray (N-dimensional array):

Arrays have important attributes: - dtype - the data type of elements - shape - dimensions of the array - ndim - number of dimensions - size - total number of elements

Multi-dimensional Arrays

Array Indexing and Slicing

NumPy arrays support powerful indexing:

Slicing Operations

The colon : notation is powerful: - A[i, :] - entire row i - A[:, j] - entire column j - A[::2, ::2] - every 2nd element in both dimensions - A[::-1, ::-1] - reverse both dimensions

Create a 5×5 array with values from 0 to 24, then: 1. Extract the middle 3×3 subarray 2. Extract every other row 3. Reverse the array (both dimensions)

TipSolution
import numpy as np

A = np.arange(25).reshape((5, 5))
print("Original:")
print(A)

middle = A[1:4, 1:4]  # Rows 1-3, columns 1-3
every_other = A[::2, :]  # Every 2nd row
reversed_array = A[::-1, ::-1]  # Reverse both

print("\nMiddle 3x3:")
print(middle)
print("\nEvery other row:")
print(every_other)
print("\nReversed:")
print(reversed_array)

Why NumPy is Fast: Vectorized Operations

The real power of NumPy comes from vectorized operations - operations on entire arrays without explicit loops:

Element-wise Operations

NumPy operations work element-by-element:

Array Reshaping and Views

NumPy can show you the same data in different shapes without copying:

The -1 in reshape means “figure out this dimension automatically”:

WarningViews vs. Copies

Most NumPy operations create views (references to the same data), not copies. This is efficient but can be surprising:

To make an independent copy, use .copy():

B = A.copy()

Broadcasting

Broadcasting allows operations between arrays of different shapes:

Broadcasting rules: 1. Arrays don’t need the same shape 2. Dimensions are compared element-wise from right to left 3. Dimensions are compatible if they’re equal or one of them is 1

Use broadcasting to: 1. Create a 5×5 multiplication table (outer product of [1,2,3,4,5] with itself) 2. Add [10, 20, 30] to each column of a 4×3 array

TipSolution
import numpy as np

# Multiplication table
x = np.arange(1, 6)
mult_table = x.reshape((5, 1)) * x  # (5,1) * (5,) broadcasts to (5,5)

print("Multiplication table:")
print(mult_table)

# Add to columns
A = np.ones((4, 3))
column_add = np.array([10, 20, 30])
result = A + column_add  # (4,3) + (3,) broadcasts

print("\nArray with column additions:")
print(result)

Useful Array Creation Functions

Array Mathematics

NumPy provides comprehensive mathematical functions:

Linear Algebra

Model exponential decay (like radioactive isotopes):

The equation is: N(t) = N₀ × e^(-λt)

Where: - N₀ = initial amount - λ = decay constant - t = time

Calculate the decay of ²³⁸U (λ = 1.55×10⁻¹⁰ yr⁻¹) over 0 to 10 billion years.

TipSolution
import numpy as np
import matplotlib.pyplot as plt

N0 = 100
lambda_decay = 1.55e-10

t = np.linspace(0, 1e10, 1000)
N = N0 * np.exp(-lambda_decay * t)

plt.figure(figsize=(8, 4))
plt.plot(t / 1e9, N)
plt.xlabel('Time (Gyr)')
plt.ylabel('Amount remaining')
plt.title('Radioactive Decay of ²³⁸U')
plt.grid(True)
plt.show()

# Earth's age is ~4.5 Gyr
earth_age_idx = 450
print(f"After 4.5 Gyr: {N[earth_age_idx]:.1f}% remains")

Summary

NumPy provides: - Fast arrays - Contiguous memory, optimized operations - Vectorization - Operations on entire arrays - Broadcasting - Automatic dimension matching - Mathematical functions - Comprehensive library - Linear algebra - Matrix operations built-in

NumPy is the foundation of scientific Python. Almost every scientific package (SciPy, matplotlib, pandas) builds on NumPy arrays.

WarningCoding scratch space