Prev: Array slicing       |       Next: Array functions

# Array operations¶

• Much of the power of arrays come from the flexibility of applying fast element-wise and array-wise operations.

## Element-wise operations¶

#### Scalars¶

• Arithmetic operations with scalars work element-wise on all array member items.
In [1]:
import numpy as np
ar = np.arange(10)
print(ar)

br = ar+1
cr = ar-1
dr = ar*2
er = ar//2

br, cr, dr, er

[0 1 2 3 4 5 6 7 8 9]

Out[1]:
(array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10]),
array([-1,  0,  1,  2,  3,  4,  5,  6,  7,  8]),
array([ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18]),
array([0, 0, 1, 1, 2, 2, 3, 3, 4, 4], dtype=int32))

#### Arrays¶

• Similarly, arithmetic operations between arrays apply element-wise between respective array member items. Note that arrays of the same shape are used in these examples.
In [2]:
import numpy as np
ar = np.arange(1,6)
br = np.arange(10,60,10)
cr = np.arange(100,600,100)

print(ar, br, cr)

[1 2 3 4 5] [10 20 30 40 50] [100 200 300 400 500]

In [3]:
ar+br+cr

Out[3]:
array([111, 222, 333, 444, 555])
In [4]:
cr-br

Out[4]:
array([ 90, 180, 270, 360, 450])
In [5]:
ar*cr

Out[5]:
array([ 100,  400,  900, 1600, 2500])
In [6]:
cr/ar

Out[6]:
array([ 100.,  100.,  100.,  100.,  100.])

#### 2D arrays operations¶

In [7]:
import numpy as np
ar = np.arange(10).reshape(2,5)
br = ar * 10
print(ar,'\n', br)

[[0 1 2 3 4]
[5 6 7 8 9]]
[[ 0 10 20 30 40]
[50 60 70 80 90]]

In [8]:
ar * br

Out[8]:
array([[  0,  10,  40,  90, 160],
[250, 360, 490, 640, 810]])
In [9]:
ar + br

Out[9]:
array([[ 0, 11, 22, 33, 44],
[55, 66, 77, 88, 99]])
In [10]:
ar - br

Out[10]:
array([[  0,  -9, -18, -27, -36],
[-45, -54, -63, -72, -81]])

• What happens if arrays are of different shapes?
• Numpy tries to bring arrays in 'compatible' shapes (if possible). The computational techniques that numpy implements on arrays in order to make them compatible are known as "broadcasting".
• When arrays can not be given compatible shapes ('cannot be broadcast together') then a relevant ValueError is reported

#### Example¶

In [11]:
import numpy as np
a = np.array([1,2,3,4])
b = 2
print(a*b)

br = [2,2,2,2]
print(a*br)

[2 4 6 8]
[2 4 6 8]

• In the simplest case of broadcasting an integer (variable b) is handled "as if" it was an one-dimensional array with N members (all of them with the same value)
• In the example above a*b multiplication produces the same outcome as a*br, where br an array like the 'broadcast' form of b integer.

• In order for numpy to succesfully broadcast two arrays: the size of the corresponding axes for both arrays (starting from the trailing axes and moving upward) must either be of the same size or one of them must be '1'
• In the example below, ar and br broadcast as shapes (1,4) and (4,1) taken in axes-pairs conform to the broadcast rule: "at least one of the axes is of size '1'"
In [12]:
import numpy as np
ar = np.arange(1,5).reshape(1,4)
br = np.arange(1,5).reshape(4,1)
print(ar,'\n',br)

ar*br

[[1 2 3 4]]
[[1]
[2]
[3]
[4]]

Out[12]:
array([[ 1,  2,  3,  4],
[ 2,  4,  6,  8],
[ 3,  6,  9, 12],
[ 4,  8, 12, 16]])
• Arrays a (2,3) and b (3,) broadcast together since they have trailing axes of the same size (3)
In [13]:
import numpy as np
a = np.array([[1,2,3],[4,5,6]])
b = np.array([5,10,15])

a * b

Out[13]:
array([[ 5, 20, 45],
[20, 50, 90]])
• Arrays ar with shape (2,3) and br with shape (3,1) do NOT broadcast. The trailing axis is OK (size of br is '1'). However, they are not compatible in the next axis where the ar size is 2 and the br size is 3.
• How would you reshape a so that they broadcast?
In [14]:
import numpy as np
ar = np.array([[1,2,3],[4,5,6]])
br = np.array([5,10,15]).reshape(3,1)
ar * br

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-14-52efda059317> in <module>()
2 ar = np.array([[1,2,3],[4,5,6]])
3 br = np.array([5,10,15]).reshape(3,1)
----> 4 ar * br

ValueError: operands could not be broadcast together with shapes (2,3) (3,1) 
• Arrays ar (2,1,4) and br (2,8,1) do broadcast together. Why? Start from trailing axes and move upward to check if broadcast rules apply.
In [15]:
import numpy as np
ar = np.array([[1,2,3,4],[4,5,6,8]]).reshape(2,1,4)
br = np.arange(10, 170, 10).reshape(2,8,1)
ar * br

Out[15]:
array([[[  10,   20,   30,   40],
[  20,   40,   60,   80],
[  30,   60,   90,  120],
[  40,   80,  120,  160],
[  50,  100,  150,  200],
[  60,  120,  180,  240],
[  70,  140,  210,  280],
[  80,  160,  240,  320]],

[[ 360,  450,  540,  720],
[ 400,  500,  600,  800],
[ 440,  550,  660,  880],
[ 480,  600,  720,  960],
[ 520,  650,  780, 1040],
[ 560,  700,  840, 1120],
[ 600,  750,  900, 1200],
[ 640,  800,  960, 1280]]])
• Arrays ar and br broadcast together. Why? As a practice, explore various shapes of the arrays to see if they broadcast
In [16]:
import numpy as np
ar = np.array([[1,2,3],[4,5,6],[7,8,9]])
br = np.array([5,10,15])
ar + br

Out[16]:
array([[ 6, 12, 18],
[ 9, 15, 21],
[12, 18, 24]])