Vectorization: Numpy makes it possible to perform operations on an entire vector rather than just one element at a time.
This creates high-performing, less verbose, and more maintainable code.
Numpy has specific functions to perform vectorized addition, subtraction, multiplication, division, and exponentiation.
import numpy as np
a=np.arange(1,11)
b=np.arange(21,31)
print("a",a)
print("b",b)
a [ 1 2 3 4 5 6 7 8 9 10] b [21 22 23 24 25 26 27 28 29 30]
# This will add the elements of each array resulting in
# a[0] + b[0], a[1] + b[1], and so on
# This functionality works for other operations as well
a+b
array([22, 24, 26, 28, 30, 32, 34, 36, 38, 40])
b-a
array([20, 20, 20, 20, 20, 20, 20, 20, 20, 20])
a*b
array([ 21, 44, 69, 96, 125, 156, 189, 224, 261, 300])
b/a
array([21. , 11. , 7.66666667, 6. , 5. , 4.33333333, 3.85714286, 3.5 , 3.22222222, 3. ])
c=np.arange(2,12)
print("c =>",c)
c => [ 2 3 4 5 6 7 8 9 10 11]
# Array a raised to the power of c corresponding element by element
a**c
array([ 1, 8, 81, 1024, 15625, 279936, 5764801, 134217728, 3486784401, 100000000000])
# Operations between an array and scalar, which will be applied
# to each element in the array
a*2
array([ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20])
np.add()
np.subtract()
np.multiply()
np.divide()
np.add(a,b)
array([22, 24, 26, 28, 30, 32, 34, 36, 38, 40])
np.subtract(b,a)
array([20, 20, 20, 20, 20, 20, 20, 20, 20, 20])
np.multiply(a,b)
array([ 21, 44, 69, 96, 125, 156, 189, 224, 261, 300])
np.divide(b,a)
array([21. , 11. , 7.66666667, 6. , 5. , 4.33333333, 3.85714286, 3.5 , 3.22222222, 3. ])
np.mod()
np.power()
np.sqrt()
np.mod(b,a)
array([0, 0, 2, 0, 0, 2, 6, 4, 2, 0])
np.power(a,c)
array([ 1, 8, 81, 1024, 15625, 279936, 5764801, 134217728, 3486784401, 100000000000])
np.sqrt(a)
array([1. , 1.41421356, 1.73205081, 2. , 2.23606798, 2.44948974, 2.64575131, 2.82842712, 3. , 3.16227766])
Used for applying arithmetic operations on arrays with differing shapes if the smaller array can be expanded to match the larger one.
Numpy starts checking for compatability between the last dimensions of both arrays. Dimensions are compatible if their axes on a one-by-one basis either have the same length or either array has the length of one.
a=np.arange(1,10).reshape(3,3)
a
array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
b=np.arange(1,4)
b
array([1, 2, 3])
Numpy copies b along the vertical axis to match a and then adds the two element by element
a+b
array([[ 2, 4, 6], [ 5, 7, 9], [ 8, 10, 12]])
c=np.arange(1,3)
c
array([1, 2])
# These two cannot be made compatible. So we get a value error.
# The last dimension of a is 3, and the last dimension of c is 2.
# So there is no way that these can be made compatible.
# a+c
d=np.arange(24).reshape(2,3,4)
d
array([[[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]], [[12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23]]])
e=np.arange(4)
e
array([0, 1, 2, 3])
d-e
array([[[ 0, 0, 0, 0], [ 4, 4, 4, 4], [ 8, 8, 8, 8]], [[12, 12, 12, 12], [16, 16, 16, 16], [20, 20, 20, 20]]])
These take an array as input and return a scalar as output. These functions include averaging, standard deviation, function for calculting the sum and product of elements in an array, etc.
These incude:
np.sum()
np.prod()
np.average()
np.min()
np.max()
np.mean()
np.std()
first_arr=np.arange(10,110,10)
first_arr
array([ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
second_arr=np.arange(10,100,10).reshape(3,3)
second_arr
array([[10, 20, 30], [40, 50, 60], [70, 80, 90]])
third_arr=np.arange(10,110,10).reshape(2,5)
third_arr
array([[ 10, 20, 30, 40, 50], [ 60, 70, 80, 90, 100]])
np.sum()
¶first_arr.sum()
550
second_arr.sum()
450
third_arr.sum()
550
# Get the sum of axis 0 only, sum of each column
second_arr.sum(axis=0)
array([120, 150, 180])
# Get the sum of axis 1 only, sum of each row
second_arr.sum(axis=1)
array([ 60, 150, 240])
np.prod()
¶first_arr.prod()
36288000000000000
second_arr.prod()
362880000000000
third_arr.prod()
36288000000000000
third_arr.prod(axis=0)
array([ 600, 1400, 2400, 3600, 5000])
np.average()
¶np.average(first_arr)
55.0
np.average(second_arr)
50.0
np.average(third_arr)
55.0
np.min()
¶np.min(first_arr)
10
np.max()
¶np.max(first_arr)
100
np.mean()
¶np.mean(first_arr)
55.0
np.std()
¶np.std(first_arr)
28.722813232690143
use
np.unique()
and pass the array in question as an argument.
first_arr=np.array([1,2,3,4,5,6,1,2,7,2,1,10,7,8])
# All the unique values from the array with no duplicates
np.unique(first_arr)
array([ 1, 2, 3, 4, 5, 6, 7, 8, 10])
second_arr=np.array([[1, 1, 2,1] ,[ 3, 1, 2,1] , [1, 1, 2, 1], [ 7, 1, 1, 1]])
second_arr
array([[1, 1, 2, 1], [3, 1, 2, 1], [1, 1, 2, 1], [7, 1, 1, 1]])
# It works the same on a two dimensional array
np.unique(second_arr)
array([1, 2, 3, 7])
# Get unique rows
# Does not print the 3rd row, because it is a duplicate
# of the first row.
np.unique(second_arr,axis=0)
array([[1, 1, 2, 1], [3, 1, 2, 1], [7, 1, 1, 1]])
# Get unique columns
# Does not print the last column, becuse it is a duplicate
# of the second column.
np.unique(second_arr,axis=1)
array([[1, 1, 2], [1, 3, 2], [1, 1, 2], [1, 7, 1]])
To get the indices of the elements, pass return_index=True
to the np.unique()
function.
We get back a tuple of two arrays:
np.unique()
np.unique(first_arr,return_index= True)
(array([ 1, 2, 3, 4, 5, 6, 7, 8, 10]), array([ 0, 1, 2, 3, 4, 5, 8, 13, 11]))
To get the value counts of the elements, pass return_counts=True
to the np.unique()
function.
We get back a tuple of two arrays:
np.unique()
np.unique(second_arr,return_counts=True)
(array([1, 2, 3, 7]), array([11, 3, 1, 1]))
np.transpose()
- as oppsed tonp.reshape()
, which takes a given array and shapes it based on the dimensions passed to it,np.transpose()
, inverts the axes, changing columns into rows and rows into columnsnp.moveaxis(input_array, orig_pos, dest_pos)
- takes an array, the original position and the destination position. It returns an array with moved axes.np.swap_axis()
- changes two axes of an array. It takes three parameters, the input array, axis 1 and axis 2.
first_2dimarr=np.arange(12).reshape((3,4))
first_2dimarr
array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])
np.transpose()
¶# The shape of the array goes from 3 rows and 4 columns to
# 4 rows and 3 columns, with the elements inverted.
np.transpose(first_2dimarr)
array([[ 0, 4, 8], [ 1, 5, 9], [ 2, 6, 10], [ 3, 7, 11]])
second_2dimarr=np.arange(6).reshape(3,2)
second_2dimarr
array([[0, 1], [2, 3], [4, 5]])
np.transpose(second_2dimarr,(1,0))
array([[0, 2, 4], [1, 3, 5]])
first_3dimarr=np.arange(24).reshape(2,3,4)
print("The shaped of the original array is: \n", first_3dimarr.shape)
print('')
print("This is the original:")
first_3dimarr
The shaped of the original array is: (2, 3, 4) This is the original:
array([[[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]], [[12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23]]])
np.moveaxis()
¶moved_axis = np.moveaxis(first_3dimarr,0,-1)
print("The shape of the array with moved axis is: \n", moved_axis.shape)
print('')
print("This is the array with the first axis [0] \nmoved to the last axis, [-1]: \n")
moved_axis
The shape of the array with moved axis is: (3, 4, 2) This is the array with the first axis [0] moved to the last axis, [-1]:
array([[[ 0, 12], [ 1, 13], [ 2, 14], [ 3, 15]], [[ 4, 16], [ 5, 17], [ 6, 18], [ 7, 19]], [[ 8, 20], [ 9, 21], [10, 22], [11, 23]]])
# Compare the two closer:
print('Original with shape ', first_3dimarr.shape, ":")
print(first_3dimarr)
print('')
print('Moved axis with shape ', moved_axis.shape, ':')
print(moved_axis)
Original with shape (2, 3, 4) : [[[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]] [[12 13 14 15] [16 17 18 19] [20 21 22 23]]] Moved axis with shape (3, 4, 2) : [[[ 0 12] [ 1 13] [ 2 14] [ 3 15]] [[ 4 16] [ 5 17] [ 6 18] [ 7 19]] [[ 8 20] [ 9 21] [10 22] [11 23]]]
np.swapaxes()
¶swapped = np.swapaxes(first_3dimarr,0,2)
swapped
array([[[ 0, 12], [ 4, 16], [ 8, 20]], [[ 1, 13], [ 5, 17], [ 9, 21]], [[ 2, 14], [ 6, 18], [10, 22]], [[ 3, 15], [ 7, 19], [11, 23]]])
# Compare the swapped axes, 0 with 2:
print('Original with shape ', first_3dimarr.shape)
print(first_3dimarr)
print('')
print('Swapped axes with shape', swapped.shape)
print(swapped)
Original with shape (2, 3, 4) [[[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]] [[12 13 14 15] [16 17 18 19] [20 21 22 23]]] Swapped axes with shape (4, 3, 2) [[[ 0 12] [ 4 16] [ 8 20]] [[ 1 13] [ 5 17] [ 9 21]] [[ 2 14] [ 6 18] [10 22]] [[ 3 15] [ 7 19] [11 23]]]
You can use slicing to reverse and array:
array[::-1]
.You can also use
np.flip(input_array, axis_to_reverse)
, which reverses the elements of the array along the specified axis while preserving the shape of the array.
arr_1dim=[10,1,9,2,8,3,7,4,6,5]
arr_1dim
[10, 1, 9, 2, 8, 3, 7, 4, 6, 5]
arr_1dim[::-1]
[5, 6, 4, 7, 3, 8, 2, 9, 1, 10]
np.flip(arr_1dim)
array([ 5, 6, 4, 7, 3, 8, 2, 9, 1, 10])
arr_2dim=np.arange(9).reshape(3,3)
arr_2dim
array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
# To reverse the entire 3 rows and 3 columns across the
# whole array, use the default
np.flip(arr_2dim)
array([[8, 7, 6], [5, 4, 3], [2, 1, 0]])
# To reverse row by row, use 1 for axis 1.
# This reordered the rows, moving the last row first
# and the first row last.
np.flip(arr_2dim,1)
array([[2, 1, 0], [5, 4, 3], [8, 7, 6]])
arr_3dim=np.arange(24).reshape(2,3,4)
arr_3dim
array([[[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]], [[12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23]]])
np.flip(arr_3dim,1)
array([[[ 8, 9, 10, 11], [ 4, 5, 6, 7], [ 0, 1, 2, 3]], [[20, 21, 22, 23], [16, 17, 18, 19], [12, 13, 14, 15]]])
np.flip(arr_3dim,2)
array([[[ 3, 2, 1, 0], [ 7, 6, 5, 4], [11, 10, 9, 8]], [[15, 14, 13, 12], [19, 18, 17, 16], [23, 22, 21, 20]]])