Index Ai Academy
Phase 0 · ToolsWorking with data

NumPy arrays

About 30 minLooking ahead: some prerequisites aren't done yet

Why this matters

Every machine learning library is built on arrays of numbers. A dataset is a 2D array. An image is a 3D array. A model's weights are arrays. And an embedding, the way models capture the meaning of text, is a 1D array of a few thousand decimals. NumPy is where this way of working comes from. PyTorch, which you'll use for deep learning, copies its style almost exactly. Learn to think in whole arrays here, and the math in Phase 2 becomes code you can run.

  • Create arrays and read their shape and dtype
  • Do math on whole arrays at once instead of looping
  • Select data with indexes, slices and boolean masks
  • Summarize along an axis, and predict how broadcasting combines shapes

Lists can't do math on themselves

Multiply a Python list by 2 and you don't get doubled numbers. You get the list twice:

clicks = [5470, 2050, 3800]
print(clicks * 2)
print([c * 2 for c in clicks])

To do math on every item of a list, you need a loop or a comprehension. NumPy's array does math on every element directly. Think of a spreadsheet column: type one formula, and it applies to every row at once.

import numpy as np

clicks = np.array([5470, 2050, 3800])
impressions = np.array([182340, 410200, 950000])

print(clicks * 2)
print(clicks / impressions)

How it works:

  • import numpy as np is the standard way to load it. Every tutorial and AI assistant writes it.
  • np.array(...) turns a list into an array.
  • clicks * 2 doubles each element.
  • clicks / impressions divides element by element: first with first, second with second.

This is called vectorized math. You write the operation once, and NumPy applies it to every element in fast, pre-built code. On large data, that's often tens to hundreds of times faster than a Python loop.

Shape and dtype

import numpy as np

spend = np.array([3120.5, 1890, 6400, 120])
table = np.array([
    [5470, 301],
    [2050, 88],
    [3800, 41],
])

print(spend.dtype, spend.shape)
print(table.dtype, table.shape, table.ndim)

Two attributes describe every array:

  • dtype is the type of every element. Unlike a list, an array holds one type throughout. spend became float64 (decimals), even though 1890 was written as a whole number. table holds whole numbers: int32 here in the browser, int64 on most computers.
  • shape gives the size along each axis (direction). (4,) is a 1D array of 4 values. (3, 2) is 3 rows by 2 columns. Shapes are written as tuples: fixed-size groups of values in parentheses. ndim is the number of axes.

Most bugs in ML code are shape bugs. So printing .shape is the first thing to do when something looks wrong.

NumPy can also create arrays for you:

import numpy as np

print(np.zeros(3))
print(np.arange(0, 10, 2))
print(np.linspace(0, 1, 5))

rng = np.random.default_rng(seed=42)
print(rng.integers(1, 7, size=5))
  • arange works like range.
  • linspace gives evenly spaced values between two ends.
  • The random generator with a seed gives the same "random" numbers every run, so experiments can be repeated.