Getting Familiar with Numpy
In the next few minutes, we shall get Numpy covered! An extremely popular core scientific computing Python library that every Machine Learning practitioner must be familiar with!
NumPy — Numerical Python is a popular Python library for large multi-dimensional array and matrix processing, with the help of a large collection of high-level mathematical functions.
It is very useful for fundamental scientific computations in Machine Learning. It is particularly useful for linear algebra, Fourier transform, and random number capabilities. High-end libraries like TensorFlow uses NumPy internally for manipulation of Tensors.
Numpy employes something called — ‘Vectorization’.
Vectorization is a powerful ability within Numpy to express operations as occurring on entire arrays rather than their individual elements.
Here’s a concise definition from Wes McKinney —
“This practice of replacing explicit loops with array expressions is commonly referred to as vectorization. In general, vectorized array operations will often be one or two (or more) orders of magnitude faster than their pure Python equivalents, with the biggest impact [seen] in any kind of numerical computations” — Source.
Why is this needed? This basically enables a program to run a lot faster and computationally simpler relative to an ordinary program.
The gist below demonstrates this very aspect.
Hence, we shall forget loops and embrace Vectorization using Numpy for Data Science, Machine and Deep Learning :)
Hope you made the most out of what Numpy and Vectorization is, let us now quickly take off with Numpy! Open a Python notebook and simultaneously execute code as you read!
Getting Started with Numpy
Numpy Installation
pip install numpy
Refer numpy · PyPI for troubleshooting
Importing Numpy
import numpy as np
Initializing an Array
n = np.array([1,2,3,4,5,6,7,8,9,10])
print(n)Out:
[ 1 2 3 4 5 6 7 8 9 10]
Generating a Numpy Array with Random Integers
n1 = np.random.randint(9,999,(4,5))
n1Out:
array([[685, 904, 953, 322, 220],
[919, 890, 581, 682, 154],
[479, 749, 146, 430, 182],
[330, 33, 930, 405, 329]])
Creating a Numpy Array with Random Float Values
n2 = np.random.uniform(9,90,[3,8])
n2Out:
array([[61.00623473, 32.99151717, 82.36365056, 64.83039314, 85.97665935, 22.03596134, 42.82392491, 45.39703135],
[46.262442, 28.94826025, 17.008214, 74.5860076, 41.018801,
30.99864407, 36.21946347, 40.80893724],
[41.8882586 , 46.27282087, 24.57065243, 37.72429426, 68.97633365,40.8597184 , 39.99579792, 20.82462527]])
Creating a Numpy Array with Randomly generated Complex Numbers
n3 = np.random.random(10) + np.random.random(10)*1j
n3
#a = np.array([10,20,40],dtype="complex")
#print(a)Out:
array([0.95684921+0.36194087j, 0.38534034+0.48054872j,
0.80468821+0.44215539j, 0.85340675+0.96173861j,
0.56802172+0.7995005j , 0.86488822+0.41566963j,
0.36902005+0.03253745j, 0.69961173+0.97159714j,
0.12345621+0.3942298j , 0.68082262+0.96007271j])
Printing Shape, Dimension and Size of Numpy Arrays
print(n1.shape, n1.ndim, n1.size)
print(n2.shape, n2.ndim, n2.size)
print(n3.shape, n3.ndim, n3.size)
C = np.random.randint(1,100,(4,4))
print(C)
print(C.shape)
print(C.ndim)
print(C.size)Out:
(4, 5) 2 20
(3, 8) 2 24
(10,) 1 10
[[59 79 38 30]
[55 61 20 20]
[33 98 59 38]
[ 4 99 22 85]]
(4, 4)
2
16
What does type(np_array) give?
type(n1)Out:
numpy.ndarray
Reshaping
A = np.arange(16)
print(A)
print(A.shape)
print(A.reshape(2,8))
print(A.reshape(4,4))Out:
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
(16,)
[[ 0 1 2 3 4 5 6 7]
[ 8 9 10 11 12 13 14 15]]
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
Addition of Two Matrices
a = np.random.randint(1,100,(4,5))
b = np.random.randint(1,100,(4,5))
print("A =\n",a)
print("\nB =\n",b)
print("\nA+B =\n",a+b)
#np.add(a,b)Out:
A =
[[66 3 4 30 88]
[65 23 88 32 34]
[69 61 85 93 37]
[36 36 77 9 47]]
B =
[[20 31 94 31 30]
[31 95 72 14 94]
[26 84 62 76 59]
[53 60 37 74 86]]
A+B =
[[ 86 34 98 61 118]
[ 96 118 160 46 128]
[ 95 145 147 169 96]
[ 89 96 114 83 133]]
Transpose of a Matrix
print(a)
print("\nTranspose of A =\n",a.T)
#print(a.transpose())
print("\nDouble Tranpose of A = A\n",(a.T).T)Out:
[[66 3 4 30 88]
[65 23 88 32 34]
[69 61 85 93 37]
[36 36 77 9 47]]Transpose of A =
[[66 65 69 36]
[ 3 23 61 36]
[ 4 88 85 77]
[30 32 93 9]
[88 34 37 47]]
Double Tranpose of A = A
[[66 3 4 30 88]
[65 23 88 32 34]
[69 61 85 93 37]
[36 36 77 9 47]]
Dot Product
m1 = np.array([[1,2],[3,4]])
m2 = np.array([[5,6],[7,8]])
np.dot(m1,m2)Out:
array([[19, 22],
[43, 50]])
Element wise Multiplication
np.multiply(55,2)
x1 = np.arange(9).reshape(3,3)
x2 = np.arange(3)
print("X1 =\n",x1)
print("\nX2 =\n",x2)
print("\nElement wise Multiplication =\n",np.multiply(x1,x2))
#print(x1*x2)Out:
X1 =
[[0 1 2]
[3 4 5]
[6 7 8]]X2 =
[0 1 2]
Element wise Multiplication =
[[ 0 1 4]
[ 0 4 10]
[ 0 7 16]]
[[ 0 1 4]
[ 0 4 10]
[ 0 7 16]]
Accessing Matrix Elements — Rows and Columns
z = np.arange(16).reshape(4,4)
print(z)
print(z[0,1]) #Element - First Row Second Column
print(z[1,3]) #Element - Second Row Fourth Column
print(z[-1,-1]) #Element - Last Row Last ColumnOut:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[12 13 14 15]]
1
7
15z1 = np.arange(27).reshape(3,3,3)
print(z1)
print(z1[0,1,2]) #Third Element of Second Array of First ArrayOut:
[[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]]
[[ 9 10 11]
[12 13 14]
[15 16 17]]
[[18 19 20]
[21 22 23]
[24 25 26]]]
5
Slicing
print(p)
print(p[2:,2:])
p1 = np.random.randint(10,200,(5,5))
print(p1)
print(p1[:-2,:-2])
p2 = np.arange(10).reshape(2,5)
print(p2)
print(p2[1,1:4])
#print(p2[0:2,2])Out:
[[102 18 48 70 91]
[ 11 72 97 75 189]
[ 27 67 161 181 60]
[120 111 57 101 61]
[ 81 122 148 109 85]]
[[161 181 60]
[ 57 101 61]
[148 109 85]]
[[171 184 111 146 159]
[141 151 53 176 154]
[ 31 197 139 112 180]
[ 97 77 78 41 158]
[ 36 145 140 81 145]]
[[171 184 111]
[141 151 53]
[ 31 197 139]]
[[0 1 2 3 4]
[5 6 7 8 9]]
[6 7 8]z1 = np.arange(10)
print(z1)
print(z1[4:])
#print(z1[:4])
#print(z1[-3:-1])
#print(z1[1:5:2])
#print(z1[::2])Out:
[0 1 2 3 4 5 6 7 8 9]
[4 5 6 7 8 9]
Reversing
R = np.random.randint(1,30,(4,4))
print(R)
R = R[::-1]
print(R)
R1 = np.array([1,2,3,4,5,6,7])
R1 = R1[::-1]
print(R1)Out:
[[12 29 4 21]
[16 9 20 15]
[18 9 7 9]
[11 18 27 1]]
[[11 18 27 1]
[18 9 7 9]
[16 9 20 15]
[12 29 4 21]]
[7 6 5 4 3 2 1]
Downloading data through URLs and importing into Numpy Arrays
from numpy import genfromtxt
N = genfromtxt('https://ndownloader.figshare.com/files/12707792', delimiter=',')
print(type(N))
print(N)
print(N[1])Out:
<class 'numpy.ndarray'>
[[ 1.07 0.44 1.5 0.2 3.2 1.18 0.09 1.44 1.52 2.44 0.78 0.02]
[ 0.27 1.13 1.72 4.14 2.66 0.61 1.03 1.4 18.16 2.24 0.29 0.5 ]]
[ 0.27 1.13 1.72 4.14 2.66 0.61 1.03 1.4 18.16 2.24 0.29 0.5 ]
Sort an array along a specific axis
arr = np.random.rand(5,5)
#sort along the row
arr.sort(axis=0)
print(arr)Out:
[[0.32367677 0.160538 0.07577069 0.02051216 0.23410999]
[0.54927129 0.20910696 0.2196075 0.22756129 0.67417506]
[0.63553217 0.56279363 0.62776371 0.32657277 0.79901529]
[0.7183594 0.69288395 0.70838123 0.52581954 0.96520237]
[0.81701677 0.79908087 0.98800108 0.54773388 0.97694313]]#sort along the column
print(np.sort(arr, axis=1))Out:
[[0.02051216 0.07577069 0.160538 0.23410999 0.32367677]
[0.20910696 0.2196075 0.22756129 0.54927129 0.67417506]
[0.32657277 0.56279363 0.62776371 0.63553217 0.79901529]
[0.52581954 0.69288395 0.70838123 0.7183594 0.96520237]
[0.54773388 0.79908087 0.81701677 0.97694313 0.98800108]]
‘Argsort’ function
arr = np.random.rand(5,5)
#along the row
print(np.argsort(arr, axis=0))Out:
[[1 1 2 2 0]
[2 2 1 3 2]
[0 4 0 1 4]
[4 3 3 0 3]
[3 0 4 4 1]]#along the column
print(np.argsort(arr, axis=1))Out:
[[4 3 2 0 1]
[0 3 1 2 4]
[3 2 4 0 1]
[3 4 0 1 2]
[4 0 1 2 3]]#if axis=None, return the indices of a flattened array
print(np.argsort(arr, axis=None))Out:
[13 12 5 18 4 8 6 7 14 3 10 24 2 11 0 19 20 21 9 15 16 17 22 1 23]
Searching an element in Numpy array
arr = np.array([1, 2, 3, 4, 5, 4, 4])
x = np.where(arr == 4)
print(x)Out:
(array([3, 5, 6]),)
Joining and Splitting Numpy Arrays
#joining
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
arr = np.concatenate((arr1, arr2))
print(arr)Out:
[1 2 3 4 5 6]#splitting
arr = np.array([1, 2, 3, 4, 5, 6])
newarr = np.array_split(arr, 3)
print(newarr)Out:
[array([1, 2]), array([3, 4]), array([5, 6])]
I know that’s a lot to take in at once! But you made it until the end! Kudos on that!
Also, do not forget to go through — NumPy Documentation
For the complete code visit—
https://gist.github.com/tanvipenumudy/71d4bccef08d018b37fe4a97272b342f (Initial Code Gist)
First Half Implementation:
Second Half Implementation: