NumPy Tutorials For Beginners

# Numpy

In machine learning, We work with numeric data which helps us in various scientific and mathematical calculations needed for machine learning algorithms.

python provides us a special library which reduces our efforts to do the complex mathematical calculation, Numpy offers us an easy and pre-built tool for doing such complex mathematical calculations for developing a machine learning algorithm.

To import numpy library just write:


```python
import numpy as np
```


# Numpy Array

Numpy array provides us a special array. So what is special about this array? Let's find out.

Here I will create two numpy array, To create a 1d array use np.array([value1, value2, value3,...])


```python
ary1 = np.array([1,2,3,4,5])

ary2 = np.array([6,7,8,9,10])
```

The special thing about numpy array is that you can treat it as matrices and vectors! We can do all the possible vector and matrix calculations with the above two arrays. Let's look at some vector calculations.

# matrix multiplication

To do matrix multiplication, python introduces us to a new operator @.


```python
matmul = ary1@ary2
```


```python
matmul
```




    130

Let's take another example but this time we will use a multidimensional array.


```python
ary1 = np.array([[1,2,3],[4,5,6],[7,8,9]])
ary2 = np.array([[1,2,3],[4,5,6],[7,8,9]])
```


```python
ary1
```




    array([[1, 2, 3],
           [4, 5, 6],
           [7, 8, 9]])




```python
ary2
```




    array([[1, 2, 3],
           [4, 5, 6],
           [7, 8, 9]])



Now, let's do matrix multiplication with these two arrays




```python
matmul = ary1@ary2
```


```python
matmul
```




    array([[ 30,  36,  42],
           [ 66,  81,  96],
           [102, 126, 150]])



So, see how python reduces our efforts with just an amazing operator @ to find the matrix multiplication!

# Broadcasting

Broadcasting is another amazing concept that makes NumPy array different. What happens if we multiply those two arrays with * operator? Let's see.



```python
mul = ary1*ary2
```


```python
mul
```




    array([[ 1,  4,  9],
           [16, 25, 36],
           [49, 64, 81]])



So, in broadcasting, each element of the array multiplied with the corresponding element in another array!
Or, In Simple words we can say element-wise multiplication.

So, you must remember where to use the @ operator and where to use * operator.

# Shape Of Array


```python
ary1.shape
```




    (3, 3)



So, the shape attribute returns a tuple with the shape of the array. We can also store the values in a variable.


```python
rows, columns = ary1.shape
```


```python
rows
```




    3




```python
columns
```




    3


# Indexing in NumPy array

Numpy array follows different indexing methods. let's quickly look into some of the interesting ways.


```python
ary1[1] #This will return the second row
```




    array([4, 5, 6])




```python
ary1[0,2] #This will return the third element of the first row.
```




    3


# Slicing

Numpy array also supports the slicing. let's look into some slicing techniques.

1. If I want to extract all the elements of the second column.


```python
ary1
```




    array([[1, 2, 3],
           [4, 5, 6],
           [7, 8, 9]])




```python
ary1[: , 1] #This means that from all the rows, extract the 2nd element.
```




    array([2, 5, 8])



2. If I want elements 5,6,8,9


```python
ary1[1: ,1: ] #This means that from all the rows starting from index 1, extract all the elements from all the column starting from index 1.
```




    array([[5, 6],
           [8, 9]])


# Finding the transpose of the matrix

Consider this matrix


```python
ary1
```




    array([[1, 2, 3],
           [4, 5, 6],
           [7, 8, 9]])



In order to find it's transpose, we just have to do


```python
ary1.T
```




    array([[1, 4, 7],
           [2, 5, 8],
           [3, 6, 9]])


# Reshaping the array

We can also reshape an array according to our needs. let's look into this array:


```python
ary1
```




    array([[1, 2, 3],
           [4, 5, 6],
           [7, 8, 9]])



This array is of shape 3x3 But I want to reshape this array into 1x9.


```python
arynew = ary1.reshape((1,9))
```


```python
arynew
```




    array([[1, 2, 3, 4, 5, 6, 7, 8, 9]])




```python
arynew.shape
```




    (1, 9)



The reshape method is a very important method in image processing! We often some-time change the dimensions of the image to reduce the mathematical calculations. 

# Finding the sum of the array

We can also find the sum of all elements in our array. The sum can be found in two ways:

1. By adding element row-wise
2. By adding the elements column-wise

For this, we use a parameter called "axis".

use axis = 0 for sum accross rows
use axis = 1 for columns


```python
ary1
```




    array([[1, 2, 3],
           [4, 5, 6],
           [7, 8, 9]])




```python
ary1.sum(axis=0) # axis = 0 will add elements row-wise.
```




    array([12, 15, 18])




```python
ary1.sum(axis=1) # axis = 1 will add elements Column-wise
```




    array([ 6, 15, 24])




```python
ary1.sum() # if you will not pass any parameter then it will add up all the elements of the array.
```




    45


# Finding statistical quantities.

You can also find mean, std deviation, covariance with NumPy

# mean


```python
ary1
```




    array([[1, 2, 3],
           [4, 5, 6],
           [7, 8, 9]])



For mean, We can find it in three ways,

1. with axis = 0 i.e Row-wise
2. with axis = 1 i.e Column-Wise
3. Without axis.


```python
ary1.mean(axis=0) #Row-wise
```




    array([4., 5., 6.])



Observe the values, They represent that the values are in float


```python
ary1.mean(axis=1)
```




    array([2., 5., 8.])




```python
ary1.mean() #recall that ary1.sum() gives 45 and there are 9 elements, then the average will be 45/9 = 5
```




    5.0



Similarly, you can find covariance, std deviation. Follow This Link for more: https://numpy.org/doc/1.18/reference/routines.statistics.html


# Vector Calculations and Linear Algebra Computation In NumPy

use linalg module to load all the linear algebra and vectors methods


```python
import numpy.linalg as lg
```

Suppose I create a vector:


```python
v = np.array([1,2,3,4])
```

# Modulus or Length of the vector

To Find the modulus of the vector, use norm() function:


```python
lg.norm(v)
```




    5.477225575051661




```python
s = np.array([6,7,8,9])
```

# To find Dot product or inner product


```python
dotproduct = np.dot(v,s) #The dot() function lies in numpy module not in linalg.
```


```python
dotproduct
```




    80

Read Following documentation for all the linalg functions: https://numpy.org/doc/1.18/reference/routines.linalg.html
# Generating Random samples

Numpy also provides us functions to generate random samples.

# np.random.rand()

Create an array of the given shape and populate it with random samples from a uniform distribution over [0, 1).


```python
np.random.rand(4) #will create 4 random samples.
```




    array([0.9357508 , 0.88702899, 0.07757345, 0.09777393])




```python
np.random.rand(3,3) # will create an array of 3x3 random samples ranging from 0,1
```




    array([[0.55102855, 0.72230073, 0.29441491],
           [0.46510251, 0.33849889, 0.15735107],
           [0.67413991, 0.13493568, 0.84495902]])



# np.random.randint(low, high, size)

This takes three-parameter and generates random samples between the low and high parameter of a given size


```python
np.random.randint(5,10,1)
```




    array([5])




```python
np.random.randint(5,10,size=(3,3))
```




    array([[7, 7, 7],
           [8, 8, 7],
           [9, 7, 8]])



# Normal Distribution

The samples generated by the normal distribution is often in the shape of bell curve. 

## np.random.normal(mean, std deviation, size)


```python
np.random.normal(5,6,100)
```




    array([  4.22749849,   5.93293104,   1.27972495,  13.16514588,
            -6.04455927, -10.78629822,   6.35226037,   1.88053831,
             4.92838597,   2.08377834,   2.81365536,   1.78897394,
            10.58127586,  12.19855096,   7.74861671,   3.11261361,
             6.50831522,  -2.74626504,  10.80026101,  -4.69209779,
             0.52392598,   8.43401936,   7.27441831,   8.48114792,
             3.39884893,  -0.03800171,   1.61265487,  11.65852244,
             6.28680454,   1.45840702,   6.76364442,   1.15669197,
             4.63845959,  12.54499092,   5.36362639,  -4.69757577,
             9.13528249,   8.90782402,   4.10504883,   2.46981845,
             8.60962967,   7.54152733,   9.15972348,   2.02184486,
            10.77384518,   4.38537905,  10.78158051,  13.92764537,
             4.21840401,   7.19279992,  -0.26586687,   8.17127075,
            -8.10350945,   0.78133623,  15.06314567,   5.1857313 ,
             2.85983272,   8.71148886,  11.36737981,   9.13170755,
            10.18619208,  -1.90851758,   2.42905763,   8.1696082 ,
            -9.33461732,   8.43329295,   5.83994729,   9.67145374,
            -7.72329127,   5.20864797,   4.2477172 ,   2.46075688,
            11.65580432,   5.3082103 ,   7.49295086,   6.04428072,
             9.61365021,   2.39413725,   7.50078273,   0.91715694,
             9.69249746,  -4.07720982,   9.82430718,   5.05109168,
             6.09110071,  16.50570187,  11.80489969,   2.16973533,
             7.83432603,   6.29357147,   2.80894702,  -5.37893154,
             1.16829065,  14.30716683,  15.23428976,   6.07605676,
             3.68239533,  -5.21203147,  12.90084896,  -2.73336165])



Just to show you guys the bell shape of the normal sample I am using the seaborn library.


```python
import seaborn as sea
```


```python
sea.kdeplot(np.random.normal(5,6,100))
```




For more random samples and distribution, visit: https://docs.scipy.org/doc/numpy-1.15.1/reference/routines.random.html.

We have covered all the required basic functions and working of numpy library to begin work with the machine learning algorithm.


```python

```