Broadcasting means replicating a multidimensional array along some of its singleton dimensions to match the size of another array. This happens automatically for Numpy arrays when arithmetic operators are applied to them.
For example, to generate a 10×10 multiplication table you can use
print(t*t[:,None]) # Or replace t[:,None] by [*zip(t)]
Try it online!
t is created as the Numpy array
[1, 2, ..., 10]. This has shape (10,), which is equivalent to (1,10). The other operand array,
t[:,None], has size (10,1). Multiplying the two arrays implicitly replicates them, so they behave as if they both had shape (10,10). The result, which also has shape (10,10), contains the products for all pairs of entries in the original arrays.