Why we need numpy array , why can't we keep on using python list ?

Numpy array althogh looks very similar to python lists but they are highly optimized for numerical computation.

Python lists may contain different data types is same list like integer, float ,string etc.

While numpy array contain element of single data type , this is main difference netween pyhton listss and numpy arrays

Numpy arrays allow vectorized operation such as element wise addition and multiplication, this is a great comfort when you are working with numerical operations

Example:

```
import numpy as np
nparr1 = np.array([1,2,3])
nparr2 = np.array([4,5,6])
# do element wise square of both numpy arrays
print(nparr1 ** 2)
print(nparr2 ** 2)
```

Output:

```
[1 4 9]
[16 25 36]
```

Now let say we want to add above two numpy array element wise, it is very simple

```
import numpy as np
nparr1 = np.array([1,2,3])
nparr2 = np.array([4,5,6])
arr_sum = nparr1 + nparr2
print(arr_sum)
```

Output:

`[5 7 9]`

Example:

```
import numpy as np
nparr1 = np.array([1,2,3])
print(np.power(nparr1, 3))
```

Output:

`[ 1 8 27]`

Example:

```
import numpy as np
nparr1 = np.array([7,8,9])
print(np.negative(nparr1))
```

Output:

`[-7 -8 -9]`

Example:

```
import numpy as np
nparr1 = np.array([1,2,3])
# take exponential of every element
exp_array = np.exp(nparr1)
# take log for every element
log_array = np.log(exp_array)
print(exp_array)
print(log_array)
```

Output:

```
[ 2.71828183 7.3890561 20.08553692]
[1. 2. 3.]
```

Example:

```
import numpy as np
import math
nparr1 = np.array([0, math.pi / 2, math.pi])
# take sine of every element
sin_array = np.sin(nparr1)
# take cosine for every element
cos_array = np.cos(nparr1)
print(sin_array)
print(cos_array)
```

Output:

```
[0.0000000e+00 1.0000000e+00 1.2246468e-16]
[ 1.000000e+00 6.123234e-17 -1.000000e+00]
```