Basics of Numpy
NumPy is the fundamental package for scientific computing in Python. It is a Python library that provides a multidimensional array object, various derived objects (such as masked arrays and matrices), and an assortment of routines for fast operations on arrays, including mathematical, logical, shape manipulation, sorting, selecting, I/O, discrete Fourier transforms basic linear algebra, basic statistical operations, random simulation and much more.
The Numpy library can be imported in the code snippet given below.
import numpy as np
Creating NumPy array
array_1d = np.array([1,2,3,4,5,6,7])
print(array_1d)
print(type(array_1d))[1 2 3 4 5 6 7]
<class 'numpy.ndarray'>
Now, creating an array of 2D NumPy array
array_2d = np.array([[2,3,4],[5,6,7]])
print(array_2d)
print(type(array_2d))[[2 3 4]
[5 6 7]]
<class 'numpy.ndarray'>
The advantages of NumPy are as follows:
- You can write vectorized code on NumPy arrays, and not on lists, which is convenient to read and write and is concise as well.
- NumPy is much faster than the standard Python ways in performing computations.
In NumPy, dimensions are called axes. In the 2-D array given above, there are two axes having two and three elements respectively. In NumPy terminology, for 2-D arrays:
● axis = 0 refers to rows, and
● axis = 1 refers to columns.
Finding element-wise matrix multiplication using list map and NumPy and see how the output is
list1 = [1,2,3,4]
list2 = [5,6,7,8]
# the list way to multiply and finding the result
list_mul = list(map(lambda x,y: x*y,list1,list2))
print(list_mul)[5, 12, 21, 32]
Now let's see NumPy way to do matrix multiplication
# The numpy array way to do it: simply the two arrays
array_1 = np.array(list1)
array_2 = np.array(list2)array_3 = array_1 * array_2
print(array_3)
print(type(array_3))[ 5 12 21 32]
<class 'numpy.ndarray'># Square a list
list_1 = [3,4,5,6]
list_squared = [i**2 for i in list_1]
# square a numpy array
array_1 = np.array(list_1)
array_squared = array_1 ** 2
print(list_squared)
print(array_squared)[9, 16, 25, 36]
[ 9 16 25 36]
Clearly, From above we can see that operating NumPy is much simpler than looping on a list
Creating a NumPy array
There is the various way in which we can create NumPy array some of the ways are as follows.
Creating from list
# We need to convert list or tuples into an array using np.array()
# Keep in mind np.array(1,2,3,4) will through an error
# pass a list or tuple as shown below
array_from_list = np.array([2,5,6,7])
array_from_tuple = np.array((1,2,3,4))
print(array_from_list)
print(array_from_tuple)[2 5 6 7]
[1 2 3 4]
Creating by initializing an array
Other commonly used functions are as follows:
● np.ones():
❖ It is used to create an array of 1s.
● np.zeros():
❖ It is used to create an array of 0s.
● np.random.random():
❖ It is used to create an array of random numbers between 0 and 1.
● np.arange():
❖ It is used to create an array with increments of fixed step size.
● np.linspace():
❖ It is used to create an array of a fixed length when the step size is unknown.
# Notice that, by default, numpy creates data type = float64
# Can provide dtype explicitly using dtype
np.ones((5,3), dtype=np.int)array([[1, 1, 1],
[1, 1, 1],
[1, 1, 1],
[1, 1, 1],
[1, 1, 1]])
In this code snippet, we will create a 4X1 zero matrix
# Creating array of zeros
np.zeros(4, dtype=np.int)array([0, 0, 0, 0])# Array of random number
np.random.random([3,4])array([[0.55789258, 0.01008686, 0.82488163, 0.61404748],
[0.39563045, 0.8491181 , 0.43426445, 0.87056902],
[0.83208821, 0.11165941, 0.29619654, 0.01831689]])
There is one more initialisation function, np.arange(), which is equivalent to the range() function.
The code to initialise 5x1
# from 10 to 100 with a step of 5
numbers = np.arange(5,100,5)
print(numbers)[ 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95]# np.linspace()
# Sometimes, you know the length of array, not the step size
# Array of length 25 between 10 and 20
np.linspace(10,20,25)array([10. , 10.41666667, 10.83333333, 11.25 , 11.66666667,
12.08333333, 12.5 , 12.91666667, 13.33333333, 13.75 ,
14.16666667, 14.58333333, 15. , 15.41666667, 15.83333333,
16.25 , 16.66666667, 17.08333333, 17.5 , 17.91666667,
18.33333333, 18.75 , 19.16666667, 19.58333333, 20. ])# Creating a 4X3 array of 7s using np.full()
# The default data type here is int only
np.full((4,3),7)array([[7, 7, 7],
[7, 7, 7],
[7, 7, 7],
[7, 7, 7]])# Given an array, np.tile() creates a new array by repeating the given array of any number of times that you want
# The default data type is int only
arr = ([0,1,2])
np.tile(arr,3)array([0, 1, 2, 0, 1, 2, 0, 1, 2])# Create a 3X3 identity matrix using np.eye()
# the default datatype is float her
np.eye(3, dtype=int)array([[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])# Create a 4x4 random array of integer ranging from 0 to 9
np.random.randint(0,10,(4,4))array([[2, 6, 6, 6],
[5, 7, 2, 1],
[7, 1, 4, 2],
[8, 6, 4, 1]])
Finding structure and content of the array
# Intialising a random 1000 X 300 array
rand_array = np.random.random((1000,300))
# Checking shape of array
print("Shape: {}".format(rand_array.shape))
print("dtype: {}".format(rand_array.dtype))
print("Dimensions: {}".format(rand_array.ndim))
print("Item size: {}".format(rand_array.itemsize))Shape: (1000, 300)
dtype: float64
Dimensions: 2
Item size: 8
Subset, Slice, Index and Iterate Through Arrays
array_1d = np.arange(10)
# Third element
print(array_1d[2])
# Specific elements
# Notice that array[2, 5, 6] will throw an error, you need to provide the indices as a list
print(array_1d[[2, 5, 6]])
# Slice third element onwards
print(array_1d[2:])
# Slice first three elements
print(array_1d[:3])
# Slice third to seventh elements
print(array_1d[2:7])
# Subset starting 0 at increment of 2
print(array_1d[0::2])2
[2 5 6]
[2 3 4 5 6 7 8 9]
[0 1 2]
[2 3 4 5 6]
[0 2 4 6 8]
Multidimensional Array
# Creating a 2-D array
array_2d = np.array([[2, 5, 7, 5], [4, 6, 8, 10], [10, 12, 15, 19]])
# Third row second column
print(array_2d[2, 1])
# Slicing the second row, and all columns
# Notice that the resultant is itself a 1-D array
print(array_2d[1, :])
# Slicing all rows and the third column
print(array_2d[:, 2])
# Slicing all rows and t12
[ 4 6 8 10]
[ 7 8 15]# Iterating over 2-D arrays
for row in array_2d:
print(row)[2 5 7 5]
[ 4 6 8 10]
[10 12 15 19]
Computation Times in NumPy and Standard Python Lists
## Comparing time taken for computation
list_1 = [i for i in range(1000000)]
list_2 = [j**2 for j in range(1000000)]
# list multiplication
import time
# store start time, time after computation, and take the difference
t0 = time.time()
product_list = list(map(lambda x, y: x*y, list_1, list_2))
t1 = time.time()
list_time = t1 - t0
print(t1-t0)
# numpy array
array_1 = np.array(list_1)
array_2 = np.array(list_2)
t0 = time.time()
array_3 = array_1*array_2
t1 = time.time()
numpy_time = t1 - t0
print(t1-t0)
print("The ratio of time taken is {}".format(list_time/numpy_time))0.10707688331604004
0.005517482757568359
The ratio of time taken is 19.40683605565638## Basics of Numpy
<br/>
NumPy is the fundamental package for scientific computing in Python. It is a Python library that provides a multidimensional array object, various derived objects (such as masked arrays and matrices), and an assortment of routines for fast operations on arrays, including mathematical, logical, shape manipulation, sorting, selecting, I/O, discrete Fourier transforms, basic linear algebra, basic statistical operations, random simulation and much more.
<br/><br/>
The Numpy library can be imported in the code snippet given below.
import numpy as np
Creating numpy array
array_1d = np.array([1,2,3,4,5,6,7])
print(array_1d)
print(type(array_1d))
Now, creating an array of 2D numpy array
array_2d = np.array([[2,3,4],[5,6,7]])
print(array_2d)
print(type(array_2d))
The advantages of NumPy are as follows:
1. You can write vectorized code on NumPy arrays, and not on lists, which is convenient
to read and write, and is concise as well.
2. NumPy is much faster than the standard Python ways in performing computations.
In NumPy, dimensions are called axes. In the 2-D array given above, there are two axes
having two and three elements respectively.
In NumPy terminology, for 2-D arrays:<br/>
● axis = 0 refers to rows, and<br/>
● axis = 1 refers to columns.
Finding element wise matrix multiplication using list map and numpy and see how the output is
list1 = [1,2,3,4]
list2 = [5,6,7,8]
# the list way to multiply and finding the result
list_mul = list(map(lambda x,y: x*y,list1,list2))
print(list_mul)
Now lets see numpy way to do matrix multipilcations
# The numpy array way to do it: simply the two arrays
array_1 = np.array(list1)
array_2 = np.array(list2)
array_3 = array_1 * array_2
print(array_3)
print(type(array_3))
# Square a list
list_1 = [3,4,5,6]
list_squared = [i**2 for i in list_1]
# square a numpy array
array_1 = np.array(list_1)
array_squared = array_1 ** 2
print(list_squared)
print(array_squared)
Clearly, From above we can see that operating numpy is much more simpler than looping on list
### Creating numpy array
There are various way in which we can create numpy array some of the ways are as follows.
**Creating from list**
# We need to convert list or tuples into an array using np.array()
# Keep in mind np.array(1,2,3,4) will through an error
# pass a list or tuple as shown below
array_from_list = np.array([2,5,6,7])
array_from_tuple = np.array((1,2,3,4))
print(array_from_list)
print(array_from_tuple)
**Creating by initializing an array**
Other commonly used functions are as follows:<br/>
● np.ones():<br/>
❖ It is used to create an array of 1s.<br/>
● np.zeros():<br/>
❖ It is used to create an array of 0s.<br/>
● np.random.random():<br/>
❖ It is used to create an array of random numbers between 0 and 1.<br/>
● np.arange():<br/>
❖ It is used to create an array with increments of fixed step size.<br/>
● np.linspace():<br/>
❖ It is used to create an array of a fixed length when the step size is unknown.<br/>
# Notice that, by default, numpy creates data type = float64
# Can provide dtype explicitly using dtype
np.ones((5,3), dtype=np.int)
In this code snippet we will create 4X1 zero matrix
# Creating array of zeros
np.zeros(4, dtype=np.int)
# Array of random number
np.random.random([3,4])
There is one more initialisation function, np.arange(), which is equivalent to the range()
function.<br/>
The code to initialise 5x1
# from 10 to 100 with a step of 5
numbers = np.arange(5,100,5)
print(numbers)
# np.linspace()
# Sometimes, you know the length of array, not the step size
# Array of length 25 between 10 and 20
np.linspace(10,20,25)
# Creating a 4X3 array of 7s using np.full()
# The default data type here is int only
np.full((4,3),7)
# Given an array, np.tile() creates a new array by repeating the given array of any number of times that you want
# The default data type is int only
arr = ([0,1,2])
np.tile(arr,3)
# Create a 3X3 identity matrix using np.eye()
# the default datatype is float her
np.eye(3, dtype=int)
# Create a 4x4 random array of integer ranging from 0 to 9
np.random.randint(0,10,(4,4))
**Finding structure and content of array**
# Intialising a random 1000 X 300 array
rand_array = np.random.random((1000,300))
# Checking shape of array
print("Shape: {}".format(rand_array.shape))
print("dtype: {}".format(rand_array.dtype))
print("Dimensions: {}".format(rand_array.ndim))
print("Item size: {}".format(rand_array.itemsize))
**Subset,Slice,Index and Iterate Through Arrays**
array_1d = np.arange(10)
# Third element
print(array_1d[2])
# Specific elements
# Notice that array[2, 5, 6] will throw an error, you need to provide the indices as a list
print(array_1d[[2, 5, 6]])
# Slice third element onwards
print(array_1d[2:])
# Slice first three elements
print(array_1d[:3])
# Slice third to seventh elements
print(array_1d[2:7])
# Subset starting 0 at increment of 2
print(array_1d[0::2])
**Multidimensional Array**
# Creating a 2-D array
array_2d = np.array([[2, 5, 7, 5], [4, 6, 8, 10], [10, 12, 15, 19]])
# Third row second column
print(array_2d[2, 1])
# Slicing the second row, and all columns
# Notice that the resultant is itself a 1-D array
print(array_2d[1, :])
# Slicing all rows and the third column
print(array_2d[:, 2])
# Slicing all rows and t
# Iterating over 2-D arrays
for row in array_2d:
print(row)
**Computation Times in NumPy and Standard Python Lists**
## Comparing time taken for computation
list_1 = [i for i in range(1000000)]
list_2 = [j**2 for j in range(1000000)]
# list multiplication
import time
# store start time, time after computation, and take the difference
t0 = time.time()
product_list = list(map(lambda x, y: x*y, list_1, list_2))
t1 = time.time()
list_time = t1 - t0
print(t1-t0)
# numpy array
array_1 = np.array(list_1)
array_2 = np.array(list_2)
t0 = time.time()
array_3 = array_1*array_2
t1 = time.time()
numpy_time = t1 - t0
print(t1-t0)
print("The ratio of time taken is {}".format(list_time/numpy_time))