Unit 4: Array Operations using NumPy
NumPy (Numerical Python, first released 2006) is the foundational library for numerical computing in Python. It introduces the ndarray, an N-dimensional homogeneous container that stores values in a single contiguous block of memory and pushes element-wise work down into compiled C loops. Everything in this unit depends on the properties of that object.
- Homogeneity: every element shares one data type (
dtype), so the whole buffer has a fixed itemsize — this is what allows contiguous storage. - Fixed shape: an array carries a
shapetuple (e.g.(3, 4)) and andim(number of axes); resizing means creating a new array. - Vectorisation: operations apply to the whole array at once with no explicit Python loop, executed in C.
- Contiguity and strides: the array knows how many bytes to jump per axis (
strides), enabling fast indexing and cheap views. - Import convention: the library is imported as
import numpy as npthroughout.
II. Arrays vs Lists
Why the ndarray replaces the built-in list for numeric work.
A. Definition and creation
An array is a homogeneous, fixed-size grid; a list is a heterogeneous, resizable sequence of pointers to objects.
- Array construction:
np.array([1, 2, 3])builds a 1-D array;np.array([[1,2],[3,4]])builds a 2×2 array. - Generators:
np.zeros((2,3)),np.ones(4),np.arange(0,10,2)→[0 2 4 6 8],np.linspace(0,1,5)→ 5 evenly spaced points including endpoints. - List by contrast:
[1, "two", 3.0]legally mixes types; an array would upcast all to a common type.
B. Storage and performance
Arrays win on both memory and speed because homogeneity removes per-element overhead.
- Memory layout: a list holds pointers to scattered Python objects; an array holds raw values in one buffer, so a million
int64values occupy ~8 MB versus far more for a list of int objects. - Speed:
a * 2on an array runs a single C loop;[x*2 for x in lst]interprets Python bytecode per element — typically 10–100× slower. - Semantics of
+: for arraysa + badds element-wise; for listsl1 + l2concatenates.
C. Applications and limitations
Choose the container to match the data.
- Use arrays for: large numeric datasets, matrix maths, image pixels, signal samples.
- Use lists for: mixed types, frequent appends, small collections where flexibility beats speed.
- Limitation: arrays are poor at growing incrementally —
np.appendcopies the whole buffer each call.
III. Data Types
How NumPy fixes and controls the type of every element.
A. The dtype object
Each array has one dtype describing element kind and size.
- Common dtypes:
int32,int64,float32,float64,bool,complex128, and<Ustrings (e.g.<U5= 5-char Unicode). - Inspection:
a.dtypereports the type;a.itemsizegives bytes per element (float64→ 8). - Explicit choice:
np.array([1,2,3], dtype=np.float32)forces 32-bit floats.
B. Type promotion and casting
Mixed inputs are promoted to a single type; conversions are done with astype.
- Upcasting rule: combining
intandfloatyieldsfloat; adding acomplexyieldscomplex. - Explicit cast:
a.astype(np.int32)returns a new array; float→int truncates toward zero, so2.9 → 2. - Overflow risk:
np.array([300], dtype=np.int8)wraps around becauseint8holds only −128…127.
np.array([1, 2, 3.5]).dtype # dtype('float64') — int promoted to floatC. Special values
Floating-point arrays can carry non-finite markers.
np.nan: "not a number", used for missing data; any arithmetic with it yieldsnan.np.inf: infinity, e.g.np.array([1.0]) / 0→infwith a warning.- Detection:
np.isnan(a)andnp.isinf(a)return boolean masks.
IV. Array Operations
Element-wise arithmetic, indexing, reshaping and reduction on the ndarray.
A. Element-wise (vectorised) arithmetic
Arithmetic operators and ufuncs act on corresponding elements without loops.
- Operators:
a + b,a - b,a * b,a / b,a ** 2all apply position by position. - Universal functions:
np.sqrt(a),np.exp(a),np.sin(a)map a C-level function across every element. - Scalar broadcast:
a + 10adds 10 to each element (the simplest broadcasting case).
a = np.array([1, 2, 3])
a ** 2 # array([1, 4, 9])B. Indexing and slicing
Arrays support list-style slicing plus multi-axis and boolean selection.
- Basic slice:
a[1:4]selects a half-open range;a[::-1]reverses. - 2-D indexing:
m[1, 2]picks row 1, column 2;m[:, 0]takes the whole first column. - Boolean mask:
a[a > 5]returns all elements greater than 5. - Views vs copies: a slice is a view sharing memory — writing to it changes the original; use
a.copy()to break the link.
C. Reshaping and combining
Shape can be reinterpreted, and arrays joined, without changing the data.
- Reshape:
a.reshape(2, 3)rearranges 6 elements into a 2×3 grid; total size must match. - Flatten/transpose:
a.ravel()returns 1-D;m.Tswaps axes. - Stacking:
np.concatenate([a, b]),np.vstack,np.hstackjoin along an axis. -1placeholder:a.reshape(3, -1)lets NumPy infer the second dimension.
D. Matrix operations
Linear-algebra products differ from element-wise ones.
- Dot/matmul:
A @ Bornp.dot(A, B)performs matrix multiplication, contracting inner dimensions. - Contrast with
*:A * Bmultiplies element-wise;A @ Bsums products across a row–column pairing. - Helpers:
np.linalg.inv(A)inverts a square matrix;np.linalg.det(A)gives the determinant.
V. Statistical Functions
Reductions that summarise an array along one axis or the whole buffer.
A. Aggregation basics
Reduction functions collapse elements to a single value or a per-axis vector.
- Core functions:
np.sum,np.mean,np.min,np.max,np.prod. - Method form:
a.sum()equalsnp.sum(a).
B. The axis argument
axis controls the direction of the reduction in multi-dimensional arrays.
axis=0: collapse rows → one result per column (down each column).axis=1: collapse columns → one result per row (across each row).- Omitted: reduces the whole array to a scalar.
m = np.array([[1, 2], [3, 4]])
m.sum(axis=0) # array([4, 6]) — column sums
m.sum(axis=1) # array([3, 7]) — row sumsC. Dispersion and order statistics
Beyond averages, NumPy quantifies spread and rank.
- Spread:
np.std(a)(standard deviation),np.var(a)(variance = std²). - Order:
np.median(a),np.percentile(a, 75)for the 75th percentile. - Positions:
np.argmin(a)andnp.argmax(a)return the index of the extreme value.
D. NaN-aware and cumulative variants
Special versions ignore missing data or retain running totals.
- NaN-safe:
np.nanmean(a),np.nansum(a)skipnaninstead of propagating it. - Cumulative:
np.cumsum(a)returns running totals,np.cumprod(a)running products — output keeps the original length.
VI. Broadcasting
The rule that lets arrays of different shapes combine without explicit copying.
A. Purpose and principle
Broadcasting stretches a smaller array across a larger one so element-wise operations line up, using no extra memory.
- Goal: avoid manually tiling data (e.g. add a row vector to every row of a matrix).
- Mechanism: dimensions are matched conceptually; the small array is treated as repeated, but no physical copy is made.
B. The broadcasting rules
Two shapes are compatible when their dimensions align under fixed rules, compared from the right.
- Rule 1 — align right: shapes are compared trailing-dimension first; missing leading dimensions are treated as 1.
- Rule 2 — stretch 1s: a dimension of size 1 is stretched to match the other; otherwise sizes must be equal.
- Rule 3 — else error: incompatible sizes raise
ValueError: operands could not be broadcast together.
# (3,3) matrix + (3,) row vector
m = np.ones((3, 3))
r = np.array([1, 2, 3])
m + r # r stretched down all 3 rowsC. Worked example — column vs row broadcast
Reshaping one operand changes how it stretches.
- Row vector
(1,3): added to a(3,3)matrix, it repeats down each row. - Column vector
(3,1): added to the same matrix, it repeats across each column.
col = np.array([[10], [20], [30]]) # shape (3,1)
m + col # 10 added to row 0, 20 to row 1, 30 to row 2D. Applications and limitations
Broadcasting underlies most vectorised numeric code but has boundaries.
- Common uses: mean-centering data (
data - data.mean(axis=0)), scaling features, outer products viaa[:, None] * b[None, :]. - Efficiency: no intermediate expanded array is built, so memory stays low.
- Limitation: shapes like
(3,)and(4,)cannot broadcast — mismatched non-1 dimensions always fail, and silent shape mistakes can produce unintended large arrays.
Did this save you a night before the exam?
LPU Notes is free, and it stays free. Ads cover part of the server bill. The rest comes out of a student's own pocket: the domain, the storage, and keeping the site up through the weeks everyone needs it at once.
The payment button didn't load. An ad blocker or a filtered network is the usual reason. to try again.
Nothing here is ever locked, and nothing unlocks. Chip in only if it was worth it. What it pays for →