Array Creation and Manipulation

Building Arrays for Science

Before you can broadcast, vectorize, or index, you need arrays. NumPy provides dozens of array creation functions, but a handful cover 95% of scientific computing needs. This section catalogs them and shows the reshape/stack/concatenate patterns that turn individual arrays into the multi-dimensional structures your computations require.

Definition:

Core Array Creation Functions

Function Purpose Example
np.zeros(shape) Array of zeros np.zeros((3, 4))
np.ones(shape) Array of ones np.ones((2, 3), dtype=np.complex128)
np.eye(n) Identity matrix np.eye(4)
np.arange(start, stop, step) Evenly spaced (by step) np.arange(0, 10, 0.5)
np.linspace(start, stop, n) Evenly spaced (by count) np.linspace(0, 1, 100)
np.logspace(start, stop, n) Log-spaced np.logspace(1, 6, 50) β€” from 10110^1 to 10610^6
np.full(shape, value) Filled with constant np.full((3, 3), np.pi)
np.empty(shape) Uninitialized (fast) np.empty((1000,)) β€” contents are garbage

Rule: prefer np.linspace over np.arange for floating-point ranges (avoids off-by-one issues from floating-point step accumulation).

Definition:

np.meshgrid

np.meshgrid creates coordinate matrices from 1-D coordinate vectors, essential for evaluating functions on 2-D grids:

x = np.linspace(-2, 2, 100)
y = np.linspace(-2, 2, 100)
X, Y = np.meshgrid(x, y)   # each has shape (100, 100)

# Evaluate 2-D Gaussian
Z = np.exp(-(X**2 + Y**2))

# Memory-efficient alternative: sparse=True
Xs, Ys = np.meshgrid(x, y, sparse=True)
# Xs has shape (1, 100), Ys has shape (100, 1)
# Broadcasting produces the same result with less memory
Z_sparse = np.exp(-(Xs**2 + Ys**2))

Definition:

reshape vs ravel vs flatten

Function Returns Copy?
a.reshape(shape) New shape, same data View if possible, copy otherwise
a.ravel() 1-D array View if possible (C-contiguous)
a.flatten() 1-D array Always a copy
a.T Transpose View (just swaps strides)
a = np.arange(12)
b = a.reshape(3, 4)       # view β€” no data copied
c = b.ravel()             # view β€” back to 1-D
d = b.flatten()           # copy β€” safe to modify

# -1 in reshape = infer this dimension
e = a.reshape(2, -1)      # shape (2, 6) β€” NumPy computes 6

Definition:

Stacking and Concatenating Arrays

Function Description Example
np.concatenate Join along existing axis np.concatenate([a, b], axis=0)
np.stack Join along new axis np.stack([a, b]) β€” adds axis 0
np.vstack Stack vertically (axis 0) np.vstack([row1, row2])
np.hstack Stack horizontally (axis 1) np.hstack([col1, col2])
np.block Build from nested lists np.block([[A, B], [C, D]])
A = np.eye(2)
B = np.ones((2, 3))
C = np.zeros((3, 2))
D = np.full((3, 3), 5)

# Block matrix: [[A, B], [C, D]]
M = np.block([[A, B], [C, D]])  # shape (5, 5)

Theorem: Reshape Returns a View When Contiguous

a.reshape(new_shape) returns a view (no copy) if and only if a is contiguous in memory (C or Fortran order) and the new shape is compatible with contiguous strides.

If the data is already contiguous, a new shape just means reinterpreting the same flat buffer with different axis lengths. No data needs to move. If the array has non-contiguous strides (e.g., from transposing a non-square matrix), the elements are not in the right order for the new shape, so a copy is required.

Example: 2-D Function Evaluation with meshgrid

Evaluate and plot f(x,y)=sin⁑(x)cos⁑(y)f(x, y) = \sin(x) \cos(y) on the domain [βˆ’Ο€,Ο€]Γ—[βˆ’Ο€,Ο€][-\pi, \pi] \times [-\pi, \pi] using np.meshgrid.

Example: Building Block Matrices

Construct the 4x4 block matrix: M=[I2A0I2]M = \begin{bmatrix} I_2 & A \\ 0 & I_2 \end{bmatrix} where A=[1234]A = \begin{bmatrix} 1 & 2 \\ 3 & 4 \end{bmatrix}.

Quick Check

What does np.arange(12).reshape(3, -1) produce?

A (3, 4) array

A (3, 12) array

An error

A (3, 3) array

Common Mistake: Floating-Point Pitfall with np.arange

Mistake:

Using np.arange with float step and expecting a precise endpoint:

a = np.arange(0, 1, 0.1)
print(len(a))  # Sometimes 10, sometimes 11 β€” depends on float rounding!

Correction:

Use np.linspace for floating-point ranges:

a = np.linspace(0, 1, 11)  # Always exactly 11 points, endpoint included

meshgrid

Creates N-D coordinate matrices from 1-D coordinate vectors, enabling vectorized evaluation of functions on grids.

Related: Broadcasting, Linspace

Array Creation

python
meshgrid, stack, concatenate, reshape patterns for scientific computing.
# Code from: ch05/python/array_creation.py
# Load from backend supplements endpoint