# NumPy Broadcasting and Element-wise Operations

Broadcasting in Numpy refers to the functionality provided by NumPy to carry out arithmetic operations on ndarrays having different dimensions. The arithmetic operations on arrays are normally done on corresponding elements.

If the arrays are of the exact same dimension then the operations are effectively performed. If the shape and dimensions of the operand arrays are not the same, element-to-element operations are not applicable.

Though, operations on arrays having dissimilar dimensions are still feasible in NumPy because of the broadcasting ability. Whichever the smaller array among the operand arrays is broadcast to the size of bigger array dimensions so that they have a common shape and operations can be performed.

#### Array with similar shapes:

``````import numpy as np
arr1 = np.array([1,2,3,4,5])
arr2= np.array([5,10, 15, 20, 25])

res = arr2 + arr1
#Output
Array addition: [ 6 12 18 24 30]

res = arr2 - arr1
print('Array subtraction:', res)
#Output:
Array subtraction: [ 4  8 12 16 20]

res = arr2 * arr1
print('Array multiplication:', res)
#Output:
Array multiplication: [  5  20  45  80 125]

res = arr2 / arr1
print('Array division:', res)
#Output:
Array division: [5. 5. 5. 5. 5.]``````

#### Arrays with different shapes:

Creating a 2-d `ndarray` `x` and a 1-d `ndarray` `y`.

``````x = np.array([[10, 20, 30], [40, 50, 60], [70, 80, 90]])
y = np.array([1, 2, 3])
print(x-y)
#Output:
[[ 9 18 27]
[39 48 57]
[69 78 87]]``````

The output shows that NumPy broadcasting internally stretches the smaller array `y` so that `x` and `y` have a common shape and operation(here subtraction) can be performed.

### Element-wise operations:

The NumPy arrays have the ability to perform arithmetic, relational and binary operations to each of its elements.

#### Arithmetic operations:

``````arr = np.array([10, 20, 30])
print(arr + 2)
print(arr - 8)
print(arr / 5)
print(arr ** 2)
print(arr % 7)``````

Output:

``````[12 22 32]
[ 2 12 22]
[2. 4. 6.]
[100 400 900]
[3 6 2]``````

#### Relational operations:

``````print("Greater than 2:", arr > 2)
print("Less than 8:", arr < 8)
print("Greater than equal to 15:", arr >= 15)
print("Less than equal to 25:", arr <= 25)
print("Not equal to 20:", arr != 20)
print("Equal to 30:", arr == 30)``````

Output:

``````Greater than 2: [ True  True  True]
Less than 8: [False False False]
Greater than equal to 15: [False  True  True]
Less than equal to 25: [ True  True False]
Not equal to 20: [ True False  True]
Equal to 30: [False False  True]``````

#### Binary Operation:

``````print('and:', arr & 10)
print('or:', arr | 9)
print('right shift:', arr >> 1)
print('left shift:', arr << 1)``````

Output:

``````and: [10  0 10]
or: [11 29 31]
right shift: [ 5 10 15]
left shift: [20 40 60]``````