NumPy Fundamentals
Create shaped arrays, replace loops with vectorized operations, and summarize data along the correct axis.
By the end, you’ll be able to…
- Explain shape, dtype, and the difference between a view and a copy.
- Perform element-wise arithmetic and broadcasting.
- Filter arrays with boolean masks.
- Summarize data along an explicit axis.
01Arrays are typed and shaped
A NumPy array is a contiguous block of values with a dtype and a shape. A one-dimensional array of five numbers has shape (5,); a two-by-three matrix has shape (2, 3). The dtype determines the operations and memory layout, so an array of integers behaves differently from an array of floats.
Create arrays with np.array, np.zeros, np.ones, np.arange, or np.linspace. Prefer specifying dtype when the default is not what you want. A Python list and a NumPy array may look similar in a printout, but only the array supports fast element-wise arithmetic and shaped operations.
import numpy as npvalues = np.array([1, 2, 3, 4], dtype=np.int64)matrix = np.array([[1, 2, 3], [4, 5, 6]])print(values.shape, values.dtype)print(matrix.shape)print(matrix[1, 2])(4,) int64 (2, 3) 6
02Vectorization replaces loops
Arithmetic on arrays applies element by element. This is not only shorter code; it lets NumPy use optimized loops and contiguous memory. Use +, -, *, /, and universal functions such as np.sqrt and np.exp. If you find yourself iterating over every element of a large array, look for a vectorized expression first.
Broadcasting aligns shapes from the right. A (2, 3) matrix plus a (3,) row vector adds the row to every row of the matrix. The smaller array is not copied in the naive sense; NumPy computes with repeated strides. A shape that cannot be aligned raises ValueError, which is usually better than silently guessing.
import numpy as npa = np.array([1, 2, 3])b = np.array([4, 5, 6])matrix = np.array([[1, 2, 3], [4, 5, 6]])row = np.array([10, 20, 30])print(a + b)print(a * 2)print(matrix + row)[5 7 9] [2 4 6] [[11 22 33] [14 25 36]]
03Views and copies have different ownership
Basic slicing returns a view: it shares the original data and reflects changes. Fancy indexing with a boolean mask or an integer array returns a copy. A copy can be modified without touching the source; a view cannot. This distinction is one of the most common sources of surprising analysis results.
Use .copy() when you need an independent array. Use boolean indexing to select rows that satisfy a condition. Combine masks with & and |, and wrap each comparison in parentheses because comparison operators bind differently from the bitwise operators.
import numpy as npvalues = np.array([10, 20, 30, 40])view = values[:2]view[0] = 99print(values)mask = values > 25print(values[mask])independent = values.copy()independent[0] = 0print(values[0])[99 20 30 40] [99 30 40] 99
04Summaries need an axis
np.mean, np.std, np.sum, np.min, and np.max operate on the whole array by default. The axis argument selects a direction: axis=0 reduces rows and produces a value per column; axis=1 reduces columns and produces a value per row. State the axis in words before writing it.
Use keepdims=True when the result must broadcast back against the original shape. Check for missing values with np.isnan before taking a mean; a single NaN propagates through the result. An honest summary reports the count, the handling of missing data, and the units.
import numpy as npscores = np.array([[80, 90, 70], [60, 75, 95]])print(scores.mean(axis=0))print(scores.mean(axis=1))print(scores.max())print(scores.mean(axis=1, keepdims=True).shape)[70. 82.5 82.5] [80. 76.66666667] 95 (2, 1)
The ideas worth keeping.
- Arrays combine a dtype, a shape, and contiguous storage.
- Vectorized operations and broadcasting replace most explicit loops.
- Views share data; copies do not. Summaries must name their axis.
Make it yours.
Type and test your code right here in the interactive workspace. Run your solution, check the output, and compare with the worked guide when ready.
Normalize a matrix by column
Create a 2x3 integer matrix. Subtract the column means and divide by the column standard deviations. Print the shape and the rounded result.
Explore a worked solution
import numpy as npmatrix = np.array([[1, 2, 3], [4, 5, 6]], dtype=float)means = matrix.mean(axis=0)stds = matrix.std(axis=0)normalized = (matrix - means) / stdsprint(normalized.shape)print(np.round(normalized, 2))Broadcasting subtracts the three column means from each row, then divides by the three column standard deviations. The result has the same (2, 3) shape as the input.
Filter outliers
Given values from 1 to 10, select values more than one standard deviation from the mean and print both the threshold and the selected values.
Explore a worked solution
import numpy as npvalues = np.arange(1, 11)mean = values.mean()std = values.std()selected = values[np.abs(values - mean) > std]print(round(mean, 2), round(std, 2))print(selected)The mask compares the absolute distance from the mean to one standard deviation. Boolean indexing returns a copy, so later changes to selected will not modify values.
What stayed with you?
Check the ideas while they’re fresh. Your answers stay in this page and feedback appears as you go.
Normalize a matrix by column
Create a 2x3 integer matrix. Subtract the column means and divide by the column standard deviations. Print the shape and the rounded result.
normalized.shape np.round(normalized 2)
Keep exploring.
The official references behind this lesson, when you want a second angle or the full details.
One lesson closer.
Reading is a start. Trying it yourself makes the connection.