Broadcasting
Normalize Rows
Divide every element in a row by that row's sum so each row sums to 1. This is a common pre-processing step: once every row is a probability vector, rows from different datasets become comparable.
By hand
With NumPy
np.array stores the matrix in a typed buffer. sum(axis=1, keepdims=True)
produces a (2, 1) column vector of row sums; dividing the (2, 3) matrix by
this (2, 1) vector broadcasts automatically — NumPy aligns the singleton
dimension and repeats the division across all three columns without an explicit
loop. The snapshot shows row_sums and the normalized result.
naive.py
data = [[3, 3, 6], [4, 2, 2]]
result = []
for row in data:
row_sum = sum(row)
norm_row = [v / row_sum for v in row]
result.append(norm_row)
print('RESULT:', [[round(v, 10) for v in row] for row in result])
library.py
import numpy as np
data = np.array([[3, 3, 6], [4, 2, 2]], dtype=float)
row_sums = data.sum(axis=1, keepdims=True)
result = data / row_sums
rv = [[round(v, 10) for v in row] for row in result.tolist()]
print('row_sums: shape:', row_sums.shape, 'dtype:', row_sums.dtype, 'values:', row_sums.tolist())
print('result: shape:', result.shape, 'dtype:', result.dtype)
print('result values:', rv)
print('RESULT:', rv)
row_sums: shape: (2, 1) dtype: float64 values: [[12.0], [8.0]]
result: shape: (2, 3) dtype: float64
result values: [[0.25, 0.25, 0.5], [0.5, 0.25, 0.25]]
RESULT: [[0.25, 0.25, 0.5], [0.5, 0.25, 0.25]]
Implementation notes
keepdims=Truepreserves the reduced axis as a size-1 dimension, giving shape(2, 1)instead of(2,). Without it, broadcasting would fail: a(2,)vector cannot be divided into a(2, 3)matrix along the row axis.- This is the
column-broadcastpattern: the(2, 1)column vector broadcasts across all 3 columns ofa, applying a different divisor to each row. - After normalization, each row sums to 1.0 (within floating-point precision), making each row a probability vector.
- The next step in standardization is z-scoring: subtract the column mean (see
center-columns) and divide by the column standard deviation — that lesson is in the roadmap statistics chapter. - Shape, dtype, and values are shown explicitly here because
ndarray.__repr__output varies with NumPy version and print options.