#### Python library NumPy

NumPy, which stands for Numeric Python, is a library (i.e. module) consisting of multi-dimensional array objects and a collection of functions for processing those arrays. Using NumPy, mathematical and logical operations on arrays can be performed. If you are already familiar with MATLAB, you might find this tutorial useful to get started with NumPy.

#### Arrays

A numpy array is a grid of values, all of the same type, and is indexed by a tuple of non-negative integers. The number of dimensions is the rank of the array; the shape of an array is a tuple of integers giving the size of the array along each dimension. See the example below:

`import numpy as np### Creating 1D arraymy_list = [1, 2, 3, 4, 5, 6, 7, 8, 9]arr1D = np.array(my_list)print("\n1D array:")print(arr1D)# Showing type of 1D arrayprint("Array is of type: ", type(arr1D)) # Showing 1D array dimensionsprint("No. of dimensions: ", arr1D.ndim) # Showing shape of 1D arrayprint("Shape of array: ", arr1D.shape) # Showing number of elements in 1D array print("Size of array: ", arr1D.size) # Showing type of elements in 1D arrayprint("Array stores elements of type: ", arr1D.dtype)### Creating 2D arraymy_matrix = [ [1,2,3], [4,5,6], [7,8,9] ]arr2D = np.array(my_matrix)print("\n2D array:")print(arr2D)# Showing type of 2D arrayprint("Array is of type: ", type(arr2D)) # Showing 2D array dimensionsprint("No. of dimensions: ", arr2D.ndim) # Showing shape of 2D array print("Shape of array: ", arr2D.shape) # Showing number of elements in 2D arrayprint("Size of array: ", arr2D.size) # Showing type of elements in 2D array print("Array stores elements of type: ", arr2D.dtype)### Creating 3D arrayarr3D = np.array([[[1, 2,3],[4, 5, 6]],[[7, 8,9],[10, 11, 12]]])print("\n3D array:")print(arr3D)# Showing type of 3D arrayprint("Array is of type: ", type(arr3D)) # Showing 3D array dimensionsprint("No. of dimensions: ", arr3D.ndim) # Showing shape of 3D array print("Shape of array: ", arr3D.shape) # Showing number of elements in 3D arrayprint("Size of array: ", arr3D.size) # Showing type of elements in 3D array print("Array stores elements of type: ", arr3D.dtype) `

Output:

`1D array:[1 2 3 4 5 6 7 8 9]Array is of type: <class 'numpy.ndarray'>No. of dimensions: 1Shape of array: (9,)Size of array: 9Array stores elements of type: int322D array:[[1 2 3][4 5 6][7 8 9]]Array is of type: <class 'numpy.ndarray'>No. of dimensions: 2Shape of array: (3, 3)Size of array: 9Array stores elements of type: int323D array:[[[ 1 2 3][ 4 5 6]][[ 7 8 9][10 11 12]]]Array is of type: <class 'numpy.ndarray'>No. of dimensions: 3Shape of array: (2, 2, 3)Size of array: 12Array stores elements of type: int32`

#### Different types of arrays

See the example below.

`import numpy as np # Creating array from list with floating-point type a = np.array([[1, 2, 3], [4, 5, 6]], dtype = 'float') print ("Array created from list:\n", a) # Creating array from tuple b = np.array((2, 4, 6, 8)) print ("\nArray created from tuple:\n", b) # Creating 3X3 arrays with all zeros and all ones separatelyc = np.zeros((3, 3)) d = np.ones((3, 3)) print ("\nAn array initialized with all zeros:\n", c) print ("\nAn array initialized with all ones:\n", d) # Create a constant value array of complex type e = np.full((3, 4), 5, dtype = 'complex') print ("\nA complex array initialized with all 7s:\n", e) # Create an array with random values f = np.random.random((3, 3)) print ("\nA random array:\n", f) # Create a sequence of integers # from 10 to 90 with steps of 10 g = np.arange(10, 90, 10) print ("\nA sequential array with steps of 10:\n", g) # Create a sequence of 6 values in range 0 to 3 h = np.linspace(0, 3, 6) print ("\nA sequential array with 6 values between 0 and 3:\n", h)# Create a 3x3 identity matrixi = np.eye(3) print ("\nA 3x3 identity matrix:\n", i) # Another 2D arrayarr = np.array([[1, 6, 3, 4], [5, 2, 4, 2], [7, 0, 8, 9]]) # Slicing array temp = arr[:2, ::2] print ("Array with first 2 rows and alternate columns(0 and 2):\n", temp) # Integer array indexing example temp = arr[[0, 1], [2, 3]] print ("\nElements at indices (0, 1), (2, 3):\n", temp)# Reshaping 3X4 sample array to 2X2X3 array newarr = arr.reshape(2, 2, 3) print ("\nOriginal array:\n", arr) print ("\nReshaped array:\n", newarr) # Flatten array arr = np.array([[1, 2, 3], [4, 5, 6]]) flarr = arr.flatten() print ("\nOriginal array:\n", arr) print ("\nFlattened array:\n", flarr)`

Output:

`Array created from list:[[1. 2. 3.][4. 5. 6.]]Array created from tuple:[2 4 6 8]An array initialized with all zeros:[[0. 0. 0.][0. 0. 0.][0. 0. 0.]]An array initialized with all ones:[[1. 1. 1.][1. 1. 1.][1. 1. 1.]]A complex array initialized with all 7s:[[5.+0.j 5.+0.j 5.+0.j 5.+0.j][5.+0.j 5.+0.j 5.+0.j 5.+0.j][5.+0.j 5.+0.j 5.+0.j 5.+0.j]]A random array:[[0.87918838 0.38423341 0.08246248][0.0905229 0.63184745 0.02988537][0.03813888 0.62311065 0.7226542 ]]A sequential array with steps of 10:[10 20 30 40 50 60 70 80]A sequential array with 6 values between 0 and 3:[0. 0.6 1.2 1.8 2.4 3. ]A 3x3 identity matrix:[[1. 0. 0.][0. 1. 0.][0. 0. 1.]]Array with first 2 rows and alternate columns(0 and 2):[[1 3][5 4]]Elements at indices (0, 1), (2, 3):[3 2]Original array:[[1 6 3 4][5 2 4 2][7 0 8 9]]Reshaped array:[[[1 6 3][4 5 2]][[4 2 7][0 8 9]]]Original array:[[1 2 3][4 5 6]]Flattened array:[1 2 3 4 5 6]`

#### Basic Operations on arrays

See the example below.

`import numpy as np a = np.array([3, 5, 7, 9]) # add 1 to every element print ("Adding 1 to every element:", a+1) # subtract 3 from each element print ("Subtracting 3 from each element:", a-3) # multiply each element by 10 print ("Multiplying each element by 10:", a*10) # square each element print ("Squaring each element:", a**2) # modify existing array a *= 2print ("Doubled each element of original array:", a) # transpose of array a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) print ("\nOriginal array:\n", a) print ("Transpose of array:\n", a.T) `

Output:

`Adding 1 to every element: [ 4 6 8 10]Subtracting 3 from each element: [0 2 4 6]Multiplying each element by 10: [30 50 70 90]Squaring each element: [ 9 25 49 81]Doubled each element of original array: [ 6 10 14 18]Original array:[[1 2 3][4 5 6][7 8 9]]Transpose of array:[[1 4 7][2 5 8][3 6 9]]`

#### Unary and Binary Operations on arrays

See the example below.

`import numpy as np ## Demonstrating unary operators arr = np.array([[1, 2, 3],                 [4, 5, 6],                 [7, 8, 9]]) print("\nArray:")print(arr,"\n")# maximum element of array print ("Largest element is:", arr.max()) print ("Row-wise maximum elements:", arr.max(axis = 1))   # minimum element of array print ("Column-wise minimum elements:", arr.min(axis = 0))   # sum of array elements print ("Sum of all array elements:", arr.sum())   # cumulative sum along each row print ("Cumulative sum along each row:\n", arr.cumsum(axis = 1)) ## Demonstrating binary operators a = np.array([[1, 2],             [3, 4]]) b = np.array([[4, 3],             [2, 1]]) print("\nFirst Array:")print(a)  print("\nSecond Array:")print(b)# add arrays print ("\nArray sum:\n", a + b)   # multiply arrays (elementwise multiplication) print ("\nArray multiplication:\n", a*b)   # matrix multiplication print ("\nMatrix multiplication:\n", a.dot(b)) `

Output:

`Array:[[1 2 3][4 5 6][7 8 9]]Largest element is: 9Row-wise maximum elements: [3 6 9]Column-wise minimum elements: [1 2 3]Sum of all array elements: 45Cumulative sum along each row:[[ 1 3 6][ 4 9 15][ 7 15 24]]First Array:[[1 2][3 4]]Second Array:[[4 3][2 1]]Array sum:[[5 5][5 5]]Array multiplication:[[4 6][6 4]]Matrix multiplication:[[ 8 5][20 13]]`

#### Applying various operations on arrays

See the example below.

`import numpy as np # create an array of sine values a = np.array([0, np.pi/2, np.pi]) print ("Sine values of array elements:", np.sin(a)) # exponential values a = np.array([0, 1, 2, 3]) print ("Exponent of array elements:", np.exp(a)) # square root of array values print ("Square root of array elements:", np.sqrt(a))arr = np.array([[1, 4, 2], [3, 9, 6], [7, -2, 5]]) # sorted array print ("Array elements in sorted order:\n", np.sort(arr, axis = None)) # sort array row-wise print ("Row-wise sorted array:\n", np.sort(arr, axis = 1)) # specify sort algorithm print ("Column wise sort by applying quick sort:\n", np.sort(arr, axis = 0, kind = 'quicksort')) `

Output:

`Sine values of array elements: [0.0000000e+00 1.0000000e+00 1.2246468e-16]Exponent of array elements: [ 1. 2.71828183 7.3890561 20.08553692]Square root of array elements: [0. 1. 1.41421356 1.73205081]Array elements in sorted order:[-2 1 2 3 4 5 6 7 9]Row-wise sorted array:[[ 1 2 4][ 3 6 9][-2 5 7]]Column wise sort by applying quick sort:[[ 1 -2 2][ 3 4 5][ 7 9 6]]`

#### Applying statistical operations

See the example below.

`import numpy as np### The function numpy.random.normal(loc, scale, size) ## creates an array of specified shape and fills it with random values ## which is actually a part of Normal (i.e. Gaussian) distribution.# loc : [float or array_like of floats] Mean of the distribution# scale : [float or array_like of floats] Standard Derivation of the distribution # size : [int or tuple of ints, optional] Size of the distributionarray = np.random.normal(3, 0.5, 5)print(array)# Minimum print("Min= ", np.min(array))# Maximum print("Max= ", np.max(array))# Mean print("Mean= ", np.mean(array))# Medianprint("Median= ", np.median(array))# Standard Derivationprint("S.D.= ", np.std(array))`

Output:

`[3.02516547 2.61613464 2.39038074 2.98752708 3.385219 ]Min= 2.390380742358035Max= 3.3852190049416486Mean= 2.8808853876041853Median= 2.9875270839461825S.D.= 0.34560942059148964`