Skip to main content
`Ctrl`+`K`

# 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.