Numpy
What is Numpy?
->It is the python library
->It is used to perform complex numerical problems
>By using python we slove basic mathematical problems
Ex: addition,sub , sqrt,
> By using numpy we can slove complex mathematical problems
Like : integral calculation, differential equations, statistics related topics(mean,median,mode)
Creating the arrays and performing operations on the array
->by default array concept is not available in the python instead we are using list
->It is the open source library
What is array and nd array
->array : it is the collection of homogeneous element. We can access the elements using Indexing.
->nd array : the arrays which are created by using numpy are called numpy arrays.
->nd-array = n-dimensional array/numpy array
1-D array ->Vector
2-D array -->Matrix
How to create an array(we can use numpy module to create an array)
a=numpy.array([10,20,30])
Print(type(a))
Print(a)
Similarities of (list and array)
->Both are used to store the data. And slicing also applicable for both
->Both are mutable.
Differences
->List is an inbuilt datatype and array is not inbuilt datatype. we need to explicitly import the numpy
library to create an array
->list can hold heterogeneous data & array homogeneous data
Creating an Array
We can create array in 2 ways:
By using array Module # We don’t use array module because there is not much library support
By using Numpy module
By using array Module:
import array
a=array.array('i',[1,2,3,4])
print(a)
print(type(a))
for i in a: # iterating the array object
print(i)
By using numpy Module:
import numpy as np
arr=np.array([1,2,3,4])
print(arr)
print(type(arr))
for i in arr:
print(i)
Numpy array Creation
#Creating an 1D - array using list and Tuple
Using List(Square brackets)
list=[1,2,3,4]
print(type(list))
arr_list=np.array(list)
print(arr)
print(type(arr_list))
Using Tuple (parenthesis)
Tuple=('Hii','This','is','Venkat')
print(type(Tuple))
arr_tuple=np.array(Tuple)
print(arr_tuple) # It is one dimensional array
print(type(arr_tuple))
#Creating a 2 dimensional array using nested list
list=[[10,20,30],[40,50,60],[70,80,90]]
arr=np.array(list)
print(arr)
print(arr.ndim) #ndim : It is used to get n.o of dimensions from the array
#Creating 3-D array using List
list=[[[1,2],[3,4]], [[5,6],[7,8]], [[9,1],[2,3]]]
print(list)
arr=np.array(list)
print(arr)
print(arr.ndim)
print(arr.shape) # It get the dimensions of the array . It returns the tuple of integers like:(3,2,2)
# (3,2,2) means it contines 3-blocks,2-rows,2-columns
print(arr.dtype) # Dtype is used to get the datatype of the elements in the list.
#If the list contains different types of elements
list=[1,2,3,4.5]
arr=np.array(list)
print(arr) #[1. ,2. ,3. ,4.5]
list1=[1,2,3,'Mukesh']
arr1=np.array(list1)
print(arr1) #[‘1’,’2’,’3’,’Mukesh’]
list2=[1,2,3,True,0]
arr2=np.array(list2)
print(arr2) # [1,2,3,1,0]
list3=[1,2.0,'Mukesh',True]
arr3=np.array(list3)
print(arr3) #[‘1’, ’2.0’, ’Mukesh’, ’True’]
Note : If the list contains different type elements. The lower type element is converted into higher type
# Create a array for a particular datatype (using dtype argument)
list=[1,2,3,4,0]
arr=np.array(list,dtype=float)
print(arr) #[1. ,2. ,3. ,4. ,0.]
arr1=np.array(list,dtype=complex)
print(arr1) #[1. +0.j ,2. +0.j ,………….]
arr2=np.array(list,dtype=bool)
print(arr2) #[True,True,True,True,False]
arr4=np.array(list,dtype=str)
print(arr4) #[‘1’,’2’,’3’,’4’,’0’]
list1=[1.0,'',3,'Muk']
arr3=np.array(list1,dtype=bool)
print(arr3) #[True,False,True,True]
#Creating the object type array
list=[1,2.0,'Mukesh',True]
arr=np.array(list,dtype=object)
print(arr)
print(arr.dtype) #object
print(type(arr))
arr1=np.array(list)
print(arr1)
print(arr1.dtype)
print(type(arr1)) #<U32
#creating a array using arange(), range(start,end,step) | range(n,m-1,s) | default value of step is 1
import numpy as np
arr=np.arange(1,11,1,dtype=float)
print(arr)
#linespace(start,stop,num=50) ,num=50 means 50 elements in the list, equaly spaced samples over
the intervals(start,stop)
arr1=np.linspace(1,30,5)
print(arr1) [1. 8.25 15.5 22.75 30. ]
arr=np.linspace(1,30,5,dtype=int)
print(arr) [1 8 15 22 30]
#Creating array using random module in numpy
import numpy as np
arr=np.random.randint(10)
print(arr) # print random value(single value) between 0 to 9
arr1=np.random.randint(10,20)
print(arr1) # Beyween 10 to 19
arr2=np.random.randint(10,100,size=10)
print(arr2) # creating an arry with size of 10
Arr5=np.random.randint(10,100,10)
arr3=np.random.randint(10,100,size=(3,4))
print(arr3) # creating 2D array 3 rows and 4 columns
arr4=np.random.randint(10,100,size=(4,3,4))
print(arr4) # creating an 3D array with 4 Blocks,3 rows in each block , 4 columns in each block
arr5=np.random.randint(10,100,10,dtype='float')
print(arr5) # It throws an error because we cannot change the dtype .default it was INT.
arr5=np.random.randint(10,100,10)
arr5_1=arr5.astype('str')
print(arr5_1) # we can use astype to change the dtype of the array.(obj_name.astype(‘dtype’))
Rand = uniform distributions
Uniform
Randn = normal distributions
Normal
#Random.rand
arr=np.random.rand(30)
print(arr) # It will 30 values.These values are ranges from [0 to 1]randomly it will print
#Random.uniform
arr=np.random.uniform(10,100,size=5)
print(arr)
arr1=np.random.uniform()
print(arr1) # It acts like a rand function (0 to 1)
arr2=np.random.uniform(10,20)
print(arr2)
#Shuffle Shuffling the array/ in multidimensional frist axis will shuffe
arr=np.random.randint(10,20,size=7)
print(arr)
np.random.shuffle(arr)
print(arr)
arr1=np.random.randint(10,20,size=(3,7))
print(arr1)
np.random.shuffle(arr1)
print(arr1) # 3 (axis=0) rows,7 (axis=1) columns
arr2=np.random.randint(10,20,size=(2,3,7))
print(arr2)
np.random.shuffle(arr2)
print(arr2) # 2 (axis=0) Blocks, 3 (axis=1) rows, 7(axis=2) columns, 0axis will shuffle
Array Attributes :
ndim = To get dimension of the array (arr.ndim)
Shape = to get shape of the array (arr.shape)
Dtype = to get data type of the elements (arr.dtype)
Size = to get size of the array(n.o of elements) (arr.size)
Iteamsize = it will give size of the array in bytes
Astype = to change the datatype of the array ( arr1.astype(‘str’) )
arr=np.array([1,2,3,4])
arr1=arr.astype('str')
print(arr1)
DataTypes:
Int ->int8(8 bits) , int(16), int(32), int(64) default (int32) I.e int8 array requires less space than int32
Float ->float(16), float(32), float(64) default(float64)
Indexing/Slicing
->To access/get the elements in the numpy array
->there are two ways
Indexing
Slicing
->Indexing:
We can access single element, zero based indexing , it supports +ve,-ve indexing
#acessing elements in 1D array
arr=np.random.randint(1,20,size=10)
print(arr)
print(arr[1],' ',arr[-1],' ',arr[0],' ',arr[-3])
#acessing elements in 2d array
arr=np.random.randint(1,20,size=(3,5))
print(arr)
print(arr[1][2],' ',arr[-2][-3],' ',arr[1][-3],arr[-2][2])
#Acessing the elements in the 3d array
arr1=np.random.randint(1,20,size=(2,3,5))
print(arr1)
arr1[1][1][2] #[i] = blocks , [j] = rows ,[k] = columns / +ve indexing starts from 0 & -ve indexing startes
from 1
->Slicing
It is the way to access the subset of an array
It can access single element or Range of elements from array based on their indices.
Syntax : I[ : : ] ->Slice operator
I[Start : End-1 : Step] # Default for Start = 0
End = len(l)
Step = 1
#Acessing elements from 1D array
arr=np.random.randint(10,30,size=10)
print(arr)
arr[1:5:1]
print(arr[:4])
print(arr[:])
print(arr[: :])
print(arr[-7:-4]) # note : The elements retrive from left to Right (not) right to left
print(arr[-1:-3:-1])
Rules :
-> All the three (Strart,End,Step) are optional but the indentation is mandatory/necessary
-> Start,end,step the values can be +ve,-ve, but step can be Zero.
-> If the Step value is +ve = we can retrieve the elements in forward direction (start to end-1)
If the Step value is -ve = we can retrieve the elements in backward direction (start to end+1)
->In forward direction end value is 0 it means Empty array
In the back ward direction end value is -1 the array is empty.
#Acessing from 2d array
arr=np.random.randint(10,30,size=(3,3))
print(arr)
arr[0:1,1:2] #arr[rows , columns] arr[start:end:step,start,end:step]
arr[2:3:1,0:5:2]
arr[:,::2] # alternative columns
arr[::2,:] # alternative rows
#Acessing the elements in 3d array /arbitrary elements
arr=np.random.randint(10,30,size=(3,5,5))
print(arr)
arr[0:1,4:5,1:2]
arr[2:3,2:3,1:5:3] # arr[block , row, column]
# The way of accesing elements(acessing particular elements irrespective of there order)
arr=np.array([10,20,30,40,50,60,70,80,90])
print(arr)
inexes=np.array([1,3,5,7])
arr[inexes]
->To acess 1d array
Arr[X] X= can be ndarray/list of indexes
->Arr[[row_indexes],[column_indexes]] #2D array
->Arr[[Indexes of 2d array],[row_indexes],[column_indexes]] # 3d array
#Accessing the elements by condition
arr=np.array([1,-3,0,5,-9,-2,10])
arr[arr>=0]
arr[arr<0]
#difference between list slicing and array slicing
#Python list slicing: if we create the copy of the list object and if we change the value the original list is
change and copy list is remain same
list=[10,20,30,40,50,60,70,80,90]
print(id(list)) #2167720917056
l2=list[::]
print(id(l2)) #2167725785984
list[0]=99999
print(list) #[99999, 20, 30, 40, 50, 60, 70, 80, 90]
print(l2) # [10, 20, 30, 40, 50, 60, 70, 80, 90]
#Array Slicing : I we the original array the copied array also changes.
arr=np.array((10,20,30,40,50,60,70,80,90))
arr1=arr[::]
arr[0]=99999
print(arr) #[99999 20 30 40 50 60 70 80 90]
print(arr1) #[99999 20 30 40 50 60 70 80 90]
# Iterating the numpy array : accessing elements one by one
#By using python loop
#By using numpy nditer() function
#by using numpy ndenumerate() finction
#By using Python loop
# To iretate the emelmets of 1D array
arr=np.random.randint(10,30,size=10)
print(arr)
for i in arr:
print(i)
#To iterate the elements of 2D array : Nested for loop ->loop inside another loop
arr1=np.random.randint(10,30,size=(3,3))
print(arr1)
for i in arr1:
for j in i:
print(j)
#To iterate the elements of 3d array : Nested for loop ->loop inside another loop
arr2=np.random.randint(10,30,size=(3,3,3))
print(arr2)
for i in arr2:
for j in i:
for k in j:
print(k)
Note : For iterating we required n n.o of loop . To overcome this loops using nditer()
#By using numpy nditer() function : it is designed to iterate to iterate elements of any dimensional
without using multiple loops
nditer : is a class present in the numpy library
nditer() : crearting an object for nditer class
arr2=np.random.randint(10,30,size=(3,3,3)) #3D array
for i in np.nditer(arr2):
print(i)
print("-----------------------------------")
arr1=np.random.randint(10,30,size=(3,3)) #2D array
for i in np.nditer(arr1):
print(i)
print("------------------------------------")
arr=np.random.randint(10,30,size=(10)) #1D array
for i in np.nditer(arr):
print(i)
#Iterating elements from sliced array
arr2=np.random.randint(10,30,size=(3,3))
for i in np.nditer(arr2[:,:2]):
print(i)
#We can get elements of our required type
arr2=np.random.randint(10,30,size=(3,3,3))
for i in np.nditer(arr2,flags=['buffered'],op_dtypes=['float']):
print(i)
print(i.dtype)
flags=['buffered'] = to store the changed type elements.we required some space that is buffer
Note : The nditer() it will return elements and not return indexes . We need to go with ndenumerate()
#By using numpy ndenumerate() function
->It will return element and particular index of the element.
arr=np.random.randint(10,30,size=(10)) #1D array
print(arr)
for index, element in np.ndenumerate(arr):
print(f'{index} is the index of {element} element')
print("-----------------------------------------------------")
arr1=np.random.randint(10,30,size=(3,3)) #2D array
print(arr1)
for index, element in np.ndenumerate(arr1):
print(f'{index} is the index of {element} element')
#Arthmetic operator [+,-,*,/,//(floor division),%,**]
# Division(/) & Floor Division(//)
-> The division returns float value
-> The floor division returns the int value. when numerator and denominator are int values.If any of the
value is float it returns float
print(10/2," ",10//2," ",10.0//2," ",10//2.0," ",10.0//2.0) #5.0 5 5.0 5.0 5.0
1.Arthmetic operator for numpy arrays
arr=np.array([10,20,30,40,50,60,70,80,90]) #1D array/arr= np.random.randint(10,30,size=(3,3))# 2Darrar
print(arr*2) #[ 20 40 60 80 100 120 140 160 180]
print(arr+2) #[12 22 32 42 52 62 72 82 92]
print(arr-2) #[ 8 18 28 38 48 58 68 78 88]
print(arr/2) #[ 5. 10. 15. 20. 25. 30. 35. 40. 45.]
print(arr//2) #[ 5 10 15 20 25 30 35 40 45]
print(arr%2) #[0 0 0 0 0 0 0 0 0]
print(arr**2) #[ 100 400 900 1600 2500 3600 4900 6400 8100]
arr**2 #array([ 100, 400, 900, 1600, 2500, 3600, 4900, 6400, 8100])
arr= np.random.randint(10,30,size=(3,3)) # 2D array
2. #Arthmetic operator with array with arrays
To perform arthmetic operator both the arrys should have same dimension,same shape,same size
arr=np.array([10,20,30])
print(arr+arr) #[20 40 60]
print(arr//arr) #[1 1 1]
print(arr**arr) #[1410065408 0 1073741824]
arrR=np.random.randint(10,30,size=(3,3)) #2D Array
print(arrR+arrR)
print(arrR//arrR)
print(arrR**arrR)
print("-------------------------------------")
arr1=np.array([10,20,30])
arr2=np.array([40,50,60])
print(arr1-arr2) #[-30 -30 -30]
print(arr1/arr2) #[0.25 0.4 0.5 ]
print(arr1%arr2) #[10 20 30]
arrRa=np.random.randint(10,30,size=(3,3)) #2D array
arrRan=np.random.randint(10,30,size=(3,3)) #2D array
print(arrRa-arrRan)
print(arrRan/arrRan)
print(arrRan%arrRan)
print('-------------------------------------')
#Numpy as inbuilt Arthemitc function
arr1=np.array([10,20])
arr2=np.array([30,40])
print(np.add(arr1,arr2)," ",np.subtract(arr1,arr2))
print(np.multiply(arr1,arr2)," ",np.divide(arr1,arr2)," ",np.floor_divide(arr1,arr2)," ",np.mod(arr1,arr2),"
",np.power(arr1,arr2))
np.subtract(arr1,arr2)
Broad Casting :
->we can perform broad casting when two arrays are different Dimensions and shapes and size.
Array manipulation functions
1.reshape() function : It is used to change the shape of the array without changing the data.
It creates a new view of an array with a different shape
Syntax : numpy.reshape(a,newshape,order='C') #newshape=int or Tuple of ints order={'C','F','A'}
default='C'
arr=np.arange(1,10)
print(arr)
arr_=np.reshape(arr,(3,3))
print(arr_)
print("------------------------------------------------------------------------------")
arr1=np.arange(1,11)
print(arr1)
arr_1=np.reshape(arr1,(5,2))
arr_1
print("-----------------------------------------------------------------------------")
arr1=np.arange(1,11)
print(arr1)
arr_1=np.reshape(arr1,(5,2),order='F') # order='F' is Column major order / order='C' is row major order
arr_1
-------------------------------------------------------------------------------------------------------------------------------------------
->reshape() not provide seperate new array object.it provide just view due to no change in data.
if I change the in the reshaped array it will reflected in the original array and vice-versa also
arr=np.arange(1,16)
arr_=np.reshape(arr,(5,3))
print(arr_)
arr_[0][0]=99999 # Change in the reshape array Original array will changes
print(arr_)
print(arr)
arr[1]=55555 # Change in the original array reshape array will change
print(arr)
print(arr_)
-------------------------------------------------------------------------------------------------------------------------------------------
->numpy is a module
->ndarray is a class present in the numpy module
->reshape() function present in the numpy module (np.reshape())
arr1=np.arange(1,19)
arr_1=np.reshape(arr1,(3,3,2))
print(arr_1)
->reshape() is a method present in the ndarray class (arr.reshape()) arr= object of the nd array
arr=np.arange(1,19)
arr_=arr.reshape(3,3,2)
arr_
-------------------------------------------------------------------------------------------------------------------------------------------
#-1 unknown dimension
arr=np.arange(1,16)
arr_=np.reshape(arr,(5,-1))
print(arr_.shape)
print(arr_)
arr_1=np.reshape(arr,(-1,5))
print(arr_1.shape)
print(arr_1)
resize() function
Syntax : numpy.resize(arr,new_shape)
->If the new array is larger than the original array. Then the new array is filled with duplicated copies of
original array
->It is the function present in numpy module
->It will create a new array
Ex:
arr=np.arange(1,7) #original array
arr_re1=np.resize(arr,(2,3)) # resize array equal n.o of elements of original array
print(arr_re1)
arr_re=np.resize(arr,(2,5)) # resize array with more n.o of elements than original array
print(arr_re)
Syntax : array_obj_name.resize(new_shape)
->If the new array is larger than the original array. Then the new array is filled with the zeroes
->It is method present in the ndarray class
->The array which is existing will be modified
Ex:
arr=np.arange(1,7)
arr.resize(2,5)
print(arr)
Difference Between reshape() and resize()
# Shape means Dimensions of the array (3,3,3) 3 blocks,3rows,3columns
# Size : total n.o elements in the dimensional array (27 elements) 1block = 9 elements
Reshape()
->It is used to change the shape of the array. Not Size
->It will not create a new array object
->the reshape will happen without changing the original array
->the size must be matched
Resize()
->It is to change the size of the array. Automatically shape and Data will change
->It will create a new array object
->They my be chance of data change in resize()
->The size need not to be matched
Flatten() : It is to convert the n dimensional array to 1D dimensionall
->Syntax : ndarray.flatten(order='C')
->It will create the new object for the new array
arr=np.random.randint(10,30,size=(3,3))
print(arr)
print(id(arr))
b=arr.flatten()
print(b)
print(id(b))
->if i change the new array The original array will not change
b[0]=99999
print(b)
print(arr)
ravel() : It is to convert the n dimensional array to 1D dimensional
->syntax : numpy.ravel(arr,order='C')
->It will not create the new object for the new array
arr=np.arange(1,7).reshape(2,3)
print(arr)
arr_r=np.ravel(arr)
print(arr_r)
->if i change the new array The original array will change
arr_r[0]=9999
print(arr_r)
print(arr)
->syntax : ndarrayObj.ravel()
arr.ravel()
print(arr)
Difference between Flatten() & ravel()
Flatten()
->It is not an numpy library function . It is a method present in the ndarray class
ndarrayObj.flatten()
->If we perform any changes in the flatten copy,Those changes won’t be reflected in the Original copy
Ravel()
->It is both numpy library function and method present in the ndarray class
Numpy.ravel(ndarrayObj,order=’C’)
ndarrayObj.ravel()
->If we perform any changes in the Ravel copy,Those changes will be reflected in the Original copy