Array Operations
Contents
Array Operations#
import numpy as np
All Python operators can be applied to NumPy arrays, where all operations work elementwise.
Mathematical Operations#
For instance, we can easily add two vectors or two matrices by using the +
operator.
a = np.array([1, 2, 3])
b = np.array([9, 8, 7])
c = a + b
print(c)
[10 10 10]
Important
Because all operations work elementwise, the *
operator on two-dimensional arrays does NOT multiply the two matrices in the mathematical sense, but simply yields the matrix of elementwise products. Mathematical matrix multiplication will be discussed in Linear Algebra Functions.
NumPy reimplements almost all mathematical functions, like sine, cosine and so on. NumPy’s functions take arrays as arguments and apply the mathematical functions elementwise. Have a look at Mathematical functions in NumPy’s documentation for a list of available functions.
a = np.array([1, 2 , 3])
b = np.sin(a)
print(b)
[0.84147098 0.90929743 0.14112001]
Hint
Functions min
and amin
are equivalent. The amin
variant exists to avoid confusion and name conflicts with Python’s built-in function min
. Writing np.min
is okay.
Important
Functions np.min
and np.minimum
do different things. With min
we get the smallest value in an array, whereas minimum
yields the elementwise minimum of two equally sized arrays. With np.argmin
we get the index (not the value) of the minimal element of an array.
Comparing Arrays#
Comparisons work elementwise, too.
a = np.array([1, 2, 3])
b = np.array([-1, 3, 3])
print(a > b)
[ True False False]
Comparisons result in NumPy arrays of data type bool
.
The function np.any
returns True
if and only if at least one item of the argument is True
.
The function np.all
returns True
if and only if all items of the argument are True
.
a = np.array([True, True, False])
print(np.any(a))
print(np.all(a))
True
False
Some of NumPy’s functions also are accessible as methods of ndarray
objects. Examples are any
and all
:
a = np.array([True, True, False])
print(a.any())
print(a.all())
True
False
To combine several conditions you might use logical_and
and friends. Using Python’s and
(and friends) results in an error, because Python tries to convert a NumPy array to a bool
value and it’s not clear how to do this (any or all?).
Broadcasting#
If dimensions of the operands of a binary operation do not fit (short vector plus long vector, for instance) an exception is raised. But in some cases NumPy uses a technique called broadcasting to make dimensions fit by cloning suitable subarrays. Examples:
a = np.array([[1, 2, 3]]) # 1 x 3
b = np.ones((4, 3)) # 4 x 3
c = a + b
print(a, '\n')
print(b, '\n')
print(c)
print(c.shape)
[[1 2 3]]
[[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]]
[[2. 3. 4.]
[2. 3. 4.]
[2. 3. 4.]
[2. 3. 4.]]
(4, 3)
a = np.array([[1, 2, 3]]) # 1 x 3
b = np.array([[1], [2], [3], [4]]) # 4 x 1
c = a + b
print(a, '\n')
print(b, '\n')
print(c, '\n')
print(c.shape)
[[1 2 3]]
[[1]
[2]
[3]
[4]]
[[2 3 4]
[3 4 5]
[4 5 6]
[5 6 7]]
(4, 3)
a = np.array([1, 2, 3]) # 3 (one-dimensional)
b = np.ones((4, 3)) # 4 x 3
c = a + b
print(a, '\n')
print(b, '\n')
print(c)
print(c.shape)
[1 2 3]
[[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]]
[[2. 3. 4.]
[2. 3. 4.]
[2. 3. 4.]
[2. 3. 4.]]
(4, 3)
Broadcasting follows two simple rules:
If one array has fewer dimensions than the other, add dimensions of size 1 till dimensions are equal.
Compare array sizes in each dimension. If they equal, do nothing. If they differ and one array has size 1 in the dimension under consideration, clone the array with size 1 sufficiently often to fit the other array’s size.
Broadcasting makes life much easier. On the one hand it allows for operations where one operand is a scalar:
a = np.array([[1, 2, 3], [4, 5, 6]]) # 2 x 3
b = 7 # 1 (one-dimensional)
c = a + b
print(a, '\n')
print(b, '\n')
print(c)
print(c.shape)
[[1 2 3]
[4 5 6]]
7
[[ 8 9 10]
[11 12 13]]
(2, 3)
On the other hand broadcasting allows for efficient column or row operations:
# multiply columns by different values
a = np.array([[1, 2, 3], [4, 5, 6]]) # 2 x 3
b = np.array([[0.5], [2]]) # 2 x 1
c = a * b
print(a, '\n')
print(b, '\n')
print(c)
print(c.shape)
[[1 2 3]
[4 5 6]]
[[0.5]
[2. ]]
[[ 0.5 1. 1.5]
[ 8. 10. 12. ]]
(2, 3)
For higher-dimensional examples have a look at Broadcasting in NumPy’s documentation.