Learn data science and machine learning by building real-world projects on Jovian

#### Assignment 2 - Numpy Array Operations

This assignment is part of the course "Data Analysis with Python: Zero to Pandas". The objective of this assignment is to develop a solid understanding of Numpy array operations. In this assignment you will:

1. Pick 5 interesting Numpy array functions by going through the documentation: https://numpy.org/doc/stable/reference/routines.html
2. Run and modify this Jupyter notebook to illustrate their usage (some explanation and 3 examples for each function). Use your imagination to come up with interesting and unique examples.
3. Upload this notebook to your Jovian profile using `jovian.commit` and make a submission here: https://jovian.ml/learn/data-analysis-with-python-zero-to-pandas/assignment/assignment-2-numpy-array-operations
5. (Optional) Check out the notebooks shared by other participants and give feedback & appreciation.

The recommended way to run this notebook is to click the "Run" button at the top of this page, and select "Run on Binder". This will run the notebook on mybinder.org, a free online service for running Jupyter notebooks.

Try to give your notebook a catchy title & subtitle e.g. "All about Numpy array operations", "5 Numpy functions you didn't know you needed", "A beginner's guide to broadcasting in Numpy", "Interesting ways to create Numpy arrays", "Trigonometic functions in Numpy", "How to use Python for Linear Algebra" etc.

NOTE: Remove this block of explanation text before submitting or sharing your notebook online - to make it more presentable.

## 5 Numpy functions you may neede in you daily bases

Write a short introduction about Numpy and list the chosen functions.

• linalg.solve(a, b)
• Numpy.polyfit(x, y, deg)+numpy.polyder(p, m=1)
• linalg.det(a)
• numpy.transpose(a, axes=None)
• numpy.poly(seq_of_zeros)

The recommended way to run this notebook is to click the "Run" button at the top of this page, and select "Run on Binder". This will run the notebook on mybinder.org, a free online service for running Jupyter notebooks.

In :
``!pip install jovian --upgrade -q``
In :
``import jovian``
In :
``jovian.commit(project='Assignment2: numpy-array-operations')``
```[jovian] Attempting to save notebook.. [jovian] Updating notebook "abouysfi/assignment2-numpy-array-operations" on https://jovian.ai [jovian] Uploading notebook.. [jovian] Uploading additional files... [jovian] Committed successfully! https://jovian.ai/abouysfi/assignment2-numpy-array-operations ```
Out:
``'https://jovian.ai/abouysfi/assignment2-numpy-array-operations'``

Let's begin by importing Numpy and listing out the functions covered in this notebook.

In :
``import numpy as np``
In :
``````# List of functions explained
function1 =  linalg.solve(a, b)
function2 = numpy.polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False)
function3 = inalg.det(a)
function4 = numpy.transpose(a, axes=None)
function5 = numpy.poly(seq_of_zeros)
``````
```--------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-26-45fc80cf68d5> in <module> 1 # List of functions explained ----> 2 function1 = linalg.solve(a, b) 3 function2 = numpy.polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False) 4 function3 = inalg.det(a) 5 function4 = numpy.transpose(a, axes=None) NameError: name 'linalg' is not defined```

### Function 1 - linalg.solve(a, b)

Solve a linear matrix equation, or system of linear scalar equations(A*X=B)

In :
``````# Example 1 - solving a system of 2 linear equtions:
# supposant we have 2 equations: (2*x+y=5 and -x+y=2)
import numpy as np
A= np.array([[2,1],[-1,1]])
B=np.array([5,2])
X=np.linalg.solve(A,B)
print(X)
print(f'the solution is x={X} and y={X}.')

``````
```[1. 3.] the solution is x=1.0 and y=3.0. ```

We can make this Program more sophisticated, by solving a system of N equations.

In :
``````# Example 2 - This program give the solution of a system of n equations (A*X=B)
import numpy as np
A= []
n = int(input('enter number of Equations: '))
for i in range(n):
# Enter the coefficients of the equation with space between them;( Ex: 1 2 3)
# Note: Number of coefficients must be equal a n.
A.append(list(map(int, input(f'Enter the coefficients of Equation {i}: ').split())))
B=list(map(int, input(f'Enter the coefficients of the Vector B: ').split()))
A=np.array(A)
B=np.array(B)
X= np.linalg.solve(A,B)
print('The Solution of the System of equations is: ')
for i in range(n):
print(f'X{i} = {X[i]:.4f}')

``````
```enter number of Equations: 5 Enter the coefficients of Equation 0: 1 2 3 4 5 Enter the coefficients of Equation 1: -1 3 6 4 2 Enter the coefficients of Equation 2: 1 0 2 3 5 Enter the coefficients of Equation 3: 2 3 1 5 7 Enter the coefficients of Equation 4: 1 2 3 1 2 Enter the coefficients of the Vector B: 0 1 2 3 1 The Solution of the System of equations is: X0 = -18.2381 X1 = 6.0952 X2 = -1.6190 X3 = -12.5714 X4 = 12.2381 ```

In :
``````# Example 3 :
import numpy as np
A= np.array([[2,1,2],[-1,1]])
B=np.array([5,2])
X=np.linalg.solve(A,B)
print(X)
print(f'the solution is x={X} and y={X}.')

``````
```<ipython-input-7-e3d0ad507c4a>:3: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray A= np.array([[2,1,2],[-1,1]]) ```
```--------------------------------------------------------------------------- LinAlgError Traceback (most recent call last) <ipython-input-7-e3d0ad507c4a> in <module> 3 A= np.array([[2,1,2],[-1,1]]) 4 B=np.array([5,2]) ----> 5 X=np.linalg.solve(A,B) 6 print(X) 7 print(f'the solution is x={X} and y={X}.') <__array_function__ internals> in solve(*args, **kwargs) /opt/conda/lib/python3.8/site-packages/numpy/linalg/linalg.py in solve(a, b) 378 """ 379 a, _ = _makearray(a) --> 380 _assert_stacked_2d(a) 381 _assert_stacked_square(a) 382 b, wrap = _makearray(b) /opt/conda/lib/python3.8/site-packages/numpy/linalg/linalg.py in _assert_stacked_2d(*arrays) 195 for a in arrays: 196 if a.ndim < 2: --> 197 raise LinAlgError('%d-dimensional array given. Array must be ' 198 'at least two-dimensional' % a.ndim) 199 LinAlgError: 1-dimensional array given. Array must be at least two-dimensional```

The matrix A must be square. If A is singular or not square, the program will raise LinAlgError

In :
``jovian.commit()``
```[jovian] Attempting to save notebook.. [jovian] Updating notebook "abouysfi/assignment2-numpy-array-operations" on https://jovian.ai [jovian] Uploading notebook.. [jovian] Uploading additional files... [jovian] Committed successfully! https://jovian.ai/abouysfi/assignment2-numpy-array-operations ```
Out:
``'https://jovian.ai/abouysfi/assignment2-numpy-array-operations'``

### Function 2 - Numpy.polyfit(x, y, deg)+numpy.polyder(p, m=1)

Fit a polynomial p(x) = p * x**deg + ... + p[deg] of degree deg to points (x, y). Returns a vector of coefficients p that minimises the squared error in the order deg, deg-1, … 0.

The Polynomial.fit class method is recommended for new code as it is more stable numerically.

In :
``````# Example 1 - Polynomial interpolation. More the DEG is high more it precise( error ---> 0)
import numpy as np
import matplotlib.pyplot as plt

x = [1,2,3,5,6,7,8,9,10,12,13,14,15,16,18,19,21,22]
y = [100,90,80,60,60,55,60,65,70,70,75,76,78,79,90,92,95,100]

poly = np.poly1d(np.polyfit(x, y, 7))

myline = np.linspace(1, 22, 100)
print(poly)
plt.scatter(x, y)
plt.plot(myline, poly(myline))
plt.show()
``````
``` 7 6 5 4 3 2 9e-06 x - 0.0007729 x + 0.0266 x - 0.4654 x + 4.291 x - 18.87 x + 25.03 x + 89.42 ``` In :
``````# Example 2 - numpy.polyder(p, m=1), m is the order of derivation.

p = np.poly1d([1,1,1,1])
p2 = np.polyder(p)

print(f'the derivation of the polynome p is :\n{p2}')``````
```the derivation of the polynome p is : 2 3 x + 2 x + 1 ```

Return the derivative of the specified order of a polynomial.

In :
``````# Example 3
import numpy as np
import matplotlib.pyplot as plt

x = [1,2,3,5,6,7,8,9]
y = [2,3,5,6,7,8,10]

poly = np.poly1d(np.polyfit(x, y, 2))

myline = np.linspace(1, 22, 100)
print(poly)
plt.scatter(x, y)
plt.plot(myline, poly(myline))
plt.show()
``````
```--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-38-23b3bd70d1e8> in <module> 6 y = [2,3,5,6,7,8,10] 7 ----> 8 poly = np.poly1d(np.polyfit(x, y, 2)) 9 10 myline = np.linspace(1, 22, 100) <__array_function__ internals> in polyfit(*args, **kwargs) /opt/conda/lib/python3.8/site-packages/numpy/lib/polynomial.py in polyfit(x, y, deg, rcond, full, w, cov) 601 raise TypeError("expected 1D or 2D array for y") 602 if x.shape != y.shape: --> 603 raise TypeError("expected x and y to have same length") 604 605 # set rcond TypeError: expected x and y to have same length```

expected x and y to have same length X and Y need to have the dimention.

In :
``jovian.commit()``
```[jovian] Attempting to save notebook.. [jovian] Updating notebook "abouysfi/assignment2-numpy-array-operations" on https://jovian.ai [jovian] Uploading notebook.. [jovian] Uploading additional files... [jovian] Committed successfully! https://jovian.ai/abouysfi/assignment2-numpy-array-operations ```
Out:
``'https://jovian.ai/abouysfi/assignment2-numpy-array-operations'``

### Function 3 - linalg.det(a)

Compute the determinant of an array.

In :
``````# Example 1
a = np.array([[2, 5], [3, -1]])
det=np.linalg.det(a)
print(f'the determinant of a is: {det:.2f}')``````
```the determinant of a is: -17.00 ```

The determinant of a 2-D array [[a, b], [c, d]] is ad - bc:

In :
``````# Example 2
a = np.array([
[1, 2, 3],
[1, 5, 4],
[7, 0, 1]])
det=np.linalg.det(a)
print(f'the determinant of a is: {det:.2f}')``````
```the determinant of a is: -46.00 ```

In :
``````# Example 3 - breaking (to illustrate when it breaks)
a = np.array([
[1, 2, 3],
[1, 5, 4],
[7, 0, 1],
[2, 1, 0]])
det=np.linalg.det(a)
print(f'the determinant of a is: {det:.2f}')``````
```--------------------------------------------------------------------------- LinAlgError Traceback (most recent call last) <ipython-input-63-4a6b539fd092> in <module> 5 [7, 0, 1], 6 [2, 1, 0]]) ----> 7 det=np.linalg.det(a) 8 print(f'the determinant of a is: {det:.2f}') <__array_function__ internals> in det(*args, **kwargs) /opt/conda/lib/python3.8/site-packages/numpy/linalg/linalg.py in det(a) 2154 a = asarray(a) 2155 _assert_stacked_2d(a) -> 2156 _assert_stacked_square(a) 2157 t, result_t = _commonType(a) 2158 signature = 'D->D' if isComplexType(t) else 'd->d' /opt/conda/lib/python3.8/site-packages/numpy/linalg/linalg.py in _assert_stacked_square(*arrays) 202 m, n = a.shape[-2:] 203 if m != n: --> 204 raise LinAlgError('Last 2 dimensions of the array must be square') 205 206 def _assert_finite(*arrays): LinAlgError: Last 2 dimensions of the array must be square```

The dimensions of the array must be square

In [ ]:
``jovian.commit()``
```[jovian] Attempting to save notebook.. ```

### Function 4 - Numpy.transpose(a, axes=None)

Reverse or permute the axes of an array; returns the modified array.

In :
``````# Example 1
M = np.arange(9).reshape((3,3))
print(M)
Mtr = np.transpose(M)
print(f'the transpose of the matrix M is:\n{Mtr}')``````
```[[0 1 2] [3 4 5] [6 7 8]] the transpose of the matrix M is: [[0 3 6] [1 4 7] [2 5 8]] ```

The transpose of a matrix is an operator which flips a matrix over its diagonal

In :
``````# Example 2
N = np.ones((2, 3, 4))

np.transpose(N).shape
``````
Out:
``(4, 3, 2)``
In :
``````# Example 3 - breaking (to illustrate when it breaks)
B = np.array([
[2, 3, 5],
[7, 11, 13]])
np.transpose(B,axes=1)``````
```--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-21-f2c972aaa379> in <module> 3 [2, 3, 5], 4 [7, 11, 13]]) ----> 5 np.transpose(B,axes=1) <__array_function__ internals> in transpose(*args, **kwargs) /opt/conda/lib/python3.8/site-packages/numpy/core/fromnumeric.py in transpose(a, axes) 651 652 """ --> 653 return _wrapfunc(a, 'transpose', axes) 654 655 /opt/conda/lib/python3.8/site-packages/numpy/core/fromnumeric.py in _wrapfunc(obj, method, *args, **kwds) 56 57 try: ---> 58 return bound(*args, **kwds) 59 except TypeError: 60 # A TypeError occurs if the object does have such a method in its ValueError: axes don't match array```

axes: tuple or list of ints, optional. If specified, it must be a tuple or list which contains a permutation of [0,1,..,N-1] where N is the number of axes of a. The i’th axis of the returned array will correspond to the axis numbered axes[i] of the input. If not specified, defaults to range(a.ndim)[::-1], which reverses the order of the axes.

In :
``jovian.commit()``
```[jovian] Attempting to save notebook.. [jovian] Updating notebook "abouysfi/assignment2-numpy-array-operations" on https://jovian.ai [jovian] Uploading notebook.. [jovian] Uploading additional files... [jovian] Committed successfully! https://jovian.ai/abouysfi/assignment2-numpy-array-operations ```
Out:
``'https://jovian.ai/abouysfi/assignment2-numpy-array-operations'``

### Function 5 - Numpy.poly(seq_of_zeros)

Find the coefficients of a polynomial with the given sequence of roots.

In :
``````# Example 1 - working
poly=np.poly((-1./2, 0, 1./2))
print(f'the coefficients of poly are: \n {poly}')
poly=np.poly1d(poly)
print(poly)
``````
```the coefficients of poly are: [ 1. 0. -0.25 0. ] 3 1 x - 0.25 x ```

Returns the coefficients of the polynomial whose leading coefficient is one for the given sequence of zeros (multiple roots must be included in the sequence as many times as their multiplicity; see Examples). A square matrix (or array, which will be treated as a matrix) can also be given, in which case the coefficients of the characteristic polynomial of the matrix are returned.

In :
``````# Example 2
Poly1 = np.array([[0, 1./3], [-1./2, 0]])
poly2=np.poly(Poly1)
z=np.poly1d(poly2)
print(poly2)
print(z)
``````
```[1. 0. 0.16666667] 2 1 x + 0.1667 ```
In :
``````# Example 3 - breaking (to illustrate when it breaks)
p=np.ones([2, 2, 3])
np.poly(p)
``````
```--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-44-3d3fc3e777da> in <module> 1 # Example 3 - breaking (to illustrate when it breaks) 2 p=np.ones([2, 2, 3]) ----> 3 np.poly(p) <__array_function__ internals> in poly(*args, **kwargs) /opt/conda/lib/python3.8/site-packages/numpy/lib/polynomial.py in poly(seq_of_zeros) 141 seq_of_zeros = seq_of_zeros.astype(mintypecode(dt.char)) 142 else: --> 143 raise ValueError("input must be 1d or non-empty square 2d array.") 144 145 if len(seq_of_zeros) == 0: ValueError: input must be 1d or non-empty square 2d array.```

If input is the wrong shape ,it will raise an error. The input must be a 1-D or square 2-D array

In :
``jovian.commit()``
```[jovian] Attempting to save notebook.. [jovian] Updating notebook "abouysfi/assignment2-numpy-array-operations" on https://jovian.ai [jovian] Uploading notebook.. [jovian] Uploading additional files... [jovian] Committed successfully! https://jovian.ai/abouysfi/assignment2-numpy-array-operations ```
Out:
``'https://jovian.ai/abouysfi/assignment2-numpy-array-operations'``

### Conclusion

Summarize what was covered in this notebook, and where to go next

``jovian.commit()``
```[jovian] Attempting to save notebook.. ```
`` ``