Saturday, June 13, 2020

Numpy Broadcasting

Numpy Broadcasting


Broadcasting refers to the capability of Numpy to handle arrays of different shapes during arithmetic operations. These operations are implemented elements by elements of fashion.

Broadcasting provides a vectorizing wrapper for array operations so that looping occurs in C instead of Python. It can be achieved without creating unnecessary copies of data and usually leads to efficient algorithm implementations. However, in some cases, broadcasting may prove not a good idea because it may proceed to inefficient use of memory that makes computation slower.

NumPy operations are normally executed on pairs of ndarrays on an entry-by-entry basis. In the best possible case, the arrays may be having the same shape to perform smoothest operations.

For example

import numpy as np

a = np.array([3.0, 2.0, 1.0])
b = np.array([2.0, 3.0, 4.0])
print(a * b)

#Output
[6. 6. 4.]

However, if the shape and dimensions of the arrays are not equal, still Numpy can perform these operations with the help of broadcasting. The smaller array is broadcast to the size of the larger array so that they have compatible shapes.

Broadcasting Rules


There are some standard broadcasting rules so that inputs unequal shapes can be applied. We  can understand broadcasting by four rules:

  • Arrays with smaller ndim are prepended 1 in its shape.
  • Size in each dimension of the output shape is the maximum of all the input sizes in that dimension.
  • An input can be used in the computation if the size of this input in any particular dimension either matches the output size in that dimension or has a value equal to 1.
  • If an input array has a dimension size of 1 in its shape, the first data entry in that dimension will be used for all calculations along that dimension.

A set of arrays is known as broadcastable if the above rules generate a valid result and one of the following holds true,

  • Arrays have exactly equal shape.
  • Arrays have an equal number of dimensions and the length of each dimension is either a common length or 1.
  • An array having too few dimensions can have its shape prepended with a dimension of length 1 so that the above-stated property is true.

For Example,

import numpy as np 
x = np.array([[0.0,0.0,0.0],[10.0,10.0,10.0],[20.0,20.0,20.0],[30.0,30.0,30.0]]) 
y = np.array([1.0,2.0,3.0]) 

print('Array X->\n') 
print(x) 
   
print('Array Y->\n') 
print(y) 
   
print('X + Y ->') 
print(x + y)

#Output
Array X->

[[ 0.  0.  0.]
 [10. 10. 10.]
 [20. 20. 20.]
 [30. 30. 30.]]
Array Y->

[1. 2. 3.]
X + Y ->
[[ 1.  2.  3.]
 [11. 12. 13.]
 [21. 22. 23.]
 [31. 32. 33.]]

The above example can be understood with the following diagram,

numpy broadcasting