Data Analysis for Engineers/Module 3

Module 3 · Section 2 of 11

Lesson 3.1 - NumPy Arrays

Target: ~9 min read - 20 min hands-on

Overview

A NumPy array is like a Python list, but every element is the same type and operations run in fast, compiled C code instead of a Python for loop - often 10-100x faster on large datasets. np.arange() and np.linspace() generate evenly spaced values; .shape and .reshape() control an array's dimensions.

We'll compare a vectorized calculation against an equivalent for loop to make the speed and clarity difference concrete.

Why This Matters (Engineering Context)

Once you're processing a full year of hourly meter data (8,760 points), a sensor stream, or a simulation output grid, loop-based Python becomes noticeably slow. Vectorized NumPy is what makes Module 2's Pandas operations fast under the hood.

Code-Along

import numpy as np
import time

# --- Three ways to build an array ---
a = np.array([1, 2, 3, 4, 5])   # from a Python list
b = np.arange(0, 10, 2)          # like range(): start, stop (EXCLUSIVE), step
c = np.linspace(0, 1, 5)         # N evenly spaced points, start & stop INCLUSIVE
print("arange:", b)
print("linspace:", c)
print("shape of a:", a.shape)    # .shape is a tuple: (5,) = 1-D, 5 elements

# reshape() re-lays the same 12 values into a 3-row x 4-column grid (no copy)
readings = np.arange(12)
grid = readings.reshape(3, 4)
print("\nReshaped 3x4 grid:\n", grid)

# --- Vectorized vs loop: [Electrical] power dissipated in 100,000 elements ---
n = 100_000
V = np.random.uniform(3.0, 12.0, n)   # n random volts, each in [3, 12)
R = 220.0                              # ohms

# Loop version: one Python-level iteration per element (slow)
start = time.time()
p_loop = []
for v in V:
    p_loop.append(v * v / R)
loop_time = time.time() - start

# Vectorized version: one array expression, run in compiled C (fast)
start = time.time()
p_vec = V * V / R
vec_time = time.time() - start

print(f"\nLoop time:       {loop_time:.4f} s")
print(f"Vectorized time: {vec_time:.4f} s")
print(f"Speedup: {loop_time / max(vec_time, 1e-9):.1f}x")
# np.allclose: are the two results equal within a tiny floating-point tolerance?
print("Results match:", np.allclose(p_loop, p_vec))

Run it: the exact speedup ratio depends on your machine; the point is that vectorized NumPy is never slower and the gap widens with array size and per-element complexity. Results match: True confirms both approaches compute the same answer.

Practice Exercises

  1. [Mechanical] Create an array of 20 evenly spaced shaft speeds between 500 and 3600 rpm using np.linspace().
  2. Reshape a 24-element np.arange(24) into a 4x6 grid, then print its .shape and .ndim.
  3. Time a vectorized sqrt(x) for 1,000,000 random values against a pure-Python loop using math.sqrt.
# Try the practice exercises here

Knowledge Check

  1. What is the main performance advantage of a NumPy array over a Python list?
  2. What does np.linspace(0, 1, 5) produce, compared to np.arange(0, 1, 5)?
  3. What attribute tells you an array's dimensions?
Answer key
  1. Operations run as fast, vectorized compiled code instead of a Python-level loop
  2. linspace gives 5 evenly spaced points including both endpoints; arange(0,1,5) uses 5 as a step, producing just [0]
  3. .shape

24 / 63 sections · Course home · Join the coaching cohort