# Introduction to NumPy(Part-I)

NumPy is the fundamental package for scientific computing in Python. It is a Python library that provides a multidimensional array object, various derived objects (such as masked arrays and matrices), and an assortment of routines for fast operations on arrays, including mathematical, logical, shape manipulation, sorting, selecting, I/O, discrete Fourier transforms basic linear algebra, basic statistical operations, random simulation and much more. It is open-source software that has many contributors.

NumPy is so fundamental that it's hard to imagine a world without it. The image below explains its gigantic usage and life without it.

But why do you need NumPy and in what ways they are helpful to us?

NumPy is easy to implement and effective at speeding up your code. This is through vectorization and NumPy’s built-in histogram function. The vectorization in itself is awesome because you can type array arithmetic like scalar arithmetic.

# Installing NumPy

First, you need to know which Python version you have. To check the installed Python version follow the following commands:

If you have Python 2 then use` python -V`

If you have Python 3 then use` python3 -V`

You will see the version of Python present in your system.

Windows user can run the following command in their command prompt

Install PIP before installing NumPy

Python 2 `pip install numpy`

Python 3 `pip3 install numpy`

# Importing NumPy

In Python, packages/libraries like NumPy, matplotlib, scipy, etc. are nothing but an extension module. Therefore, whenever you want to use an attribute of the NumPy library, you have to import it as a header file. For the sake of convenience, we have created “np” an alias of NumPy. This alias is widely popular in the data science world.

`import numpy as np`

Arrays in NumPy

`>>> import numpy as np>>> arr=np.array([1,2,3,4,5,6,7,7,8,9])>>> print(arr)[1 2 3 4 5 6 7 7 8 9]>>> arr>>> array([1, 2, 3, 4, 5, 6, 7, 7, 8, 9])>>> arr.dtypedtype('int32')>>> print("No. of dimensions: ", arr.ndim)No. of dimensions:  1>>> print("Shape of array: ", arr.shape)Shape of array:  (10,)>>> print("Size of array: ", arr.size)Size of array:  10>>> a=np.array(1,2,3,4,5) #INCORRECT WAY Traceback (most recent call last):  File "<stdin>", line 1, in <module>ValueError: only 2 non-keyword arguments accepted`

Array creation: There are several ways of creating an array in Python. For example, you can create an array from a regular Python list or tuple using the `array` function. The type of the resulting array is deduced from the type of the elements in the sequences.

NumPy has a function named` arange`. It helps in creating the one-dimensional array. For creating a multi-dimensional array you need to reshape it. To make it a multi-dimensional array, chain its output with the `reshape` function.

`>>>import Numpy as np>>>array = np.arange(10)# ONE DIMENSIONAL ARRAY>>>array>>>array([0,  1,  2,  3,  4, 5,  6,  7,  8,  9])#MULTI-DIMENSIONAL ARRAY>>>array = np.arange(10).reshape(2,5)>>>arrayarray([[ 0,  1,  2,  3,  4],       [ 5,  6,  7,  8,  9]])#It will be craete 10 intergers and then convert the array into a two-dimensional array with 2rows and 5 columns.`

Python has many other functions like `zeros`and `ones` to quickly create and populate an array.

You can use the `zeros` function to create an array filled with zeros. The parameters to the function represent the number of rows and columns (or its dimensions).

`>>>np.zeros((4,5))array([[0., 0., 0., 0., 0.],       [0., 0., 0., 0., 0.],       [0., 0., 0., 0., 0.],       [0., 0., 0., 0., 0.]])`

You can use the `ones` function to create an array filled with ones.

`>>>np.ones((4,5))array([[1,1,1,1,1],          [1,1,1,1,1],          [1,1,1,1,1],          [1,1,1,1,1]])`

The `empty` function creates an array. Its initial content is random and depends on the state of the memory.

`>>> np.empty((4,5))array([[6.23042070e-307, 4.67296746e-307, 1.69121096e-306,        3.11522054e-307, 1.42413555e-306],       [1.78019082e-306, 1.37959740e-306, 6.23057349e-307,        1.02360935e-306, 1.69120416e-306],       [1.78022342e-306, 6.23058028e-307, 1.06811422e-306,        1.33508761e-307, 1.78022342e-306],       [1.05700345e-307, 1.11261977e-306, 1.69113762e-306,        1.33511562e-306, 2.18565567e-312]])`

The `full` function creates a n * n array filled with the given value.

The `eye` function lets you create a n * n matrix with the diagonal 1s and the others 0.

The function `linspace` returns evenly spaced numbers over a specified interval.

`>>> np.linspace(0,5,10)array([0.        , 0.55555556, 1.11111111, 1.66666667, 2.22222222,       2.77777778, 3.33333333, 3.88888889, 4.44444444, 5.        ])`

You can also use special library functions to create arrays. For example, to create an array filled with random values between 0 and 1, use `random` the function. This is particularly useful for problems where you need a random state to get started.

The numpy.ravel() functions return a contiguous flattened array(1D array with all the input-array elements and with the same type as it). A copy is made only if needed.

`SYNATX: numpy.ravel(array, order = 'C')`

The numpy.flatten() functions returns copy of n-dimensional into one-dimensional array. It flattens source array into one-dimensional.

`SYNTAX: numpy.flatten(array,order='C')`

Here I got something interesting. I used both the functions ravel() and flatten() on the same array. The output of both the function was the same list. So what’s the actual difference between the two functions?

`import numpy as npy = np.array(((1,2,3),(4,5,6),(7,8,9)))OUTPUT:print(y.flatten())[1   2   3   4   5   6   7   8   9]print(y.ravel())[1   2   3   4   5   6   7   8   9]`

Here’s what I got -

• `flatten` always returns a copy.
• `ravel` returns a view of the original array whenever possible. This isn't visible in the printed output, but if you modify the array returned by ravel, it may modify the entries in the original array. If you modify the entries in an array returned from flattening this will never happen. ravel will often be faster since no memory is copied, but you have to be more careful about modifying the array it returns.

# Indexing and slicing arrays

Indexing is used to obtain individual elements from an array, but it can also be used to obtain entire rows, columns, or planes from multi-dimensional arrays.

`>>>import numpy as np>>>arr=np.array([0,1,2,3,4,5,6,7,8,9])>>>arr # output: 8>>>arr.reshape(2,5)>>>arrarray([[0,1,2,3,4],       [5,6,7,8,9]])Note : Our array is temporarily changed.>>>arr=arr.reshape(2,5)#this changes our one-dimensional array to two-dimensional array permanently.>>>arr[1,4]# output: 9`

In a 2-D array,

• the first index selects the row
• the second index selects the column

In a 3-D array,

• The first index, i, selects the matrix
• The second index, j, selects the row
• The third index, k, select the column

Slicing:

`>>> arr[1:8]array([1, 2, 3, 4, 5, 6, 7])>>>arr=arr.reshape(2,5)>>> arr[1:,2:4]array([[7, 8]])`

# Linear Algebra

The Linear Algebra module of NumPy offers various methods to apply linear algebra on NumPy array. Some of them are list below-

• rank, determinant, trace, etc. of an array.
• eigenvalues of matrices
• matrix and vector products (dot, inner, outer, etc. product), matrix exponentiation
• solve linear or tensor equations and much more!

NumPy Matrix

`>>> A = np.array([[ 1, 2 ,3], [ 4, 5 ,6]])>>> B = np.array([7,8,9]) >>> Aarray([[1, 2, 3],       [4, 5, 6]])>>> Barray([7, 8, 9])>>> A.shape(2, 3)>>> B.shape(3,)>>> A.Tarray([[1, 4],       [2, 5],       [3, 6]])>>> >>> B.Tarray([7, 8, 9])>>> >>> A.dot(B)array([ 50, 122])>>> >>> np.dot(A,B)`

# Ax = b : numpy.linalg

Now we want to solve Ax = b:

`>>> import numpy as np>>> from numpy.linalg import solve>>> A = np.array([[1,2],[3,4]])>>> Aarray([[1, 2],       [3, 4]])>>> b = np.array([10, 20])>>> b>>> x = solve(A,b)>>> xarray([ 0.,  5.])>>> a = np.array([[3,-9],[2,5]])>>> np.linalg.det(a)33.000000000000014`

Eigenvalue and vectors: The eig returns two tuples: the first one is the eigen values and the second one is a matrix whose columns are the two eigen vectors.

`>>>from numpy.linalg import eig>>> arr=np.array([[1,2],[3,4]])>>> arrarray([[1, 2],       [3, 4]])>>> eig(arr)(array([-0.37228132,  5.37228132]), array([[-0.82456484, -0.41597356],       [ 0.56576746, -0.90937671]]))`

Python is just an ocean of modules. Get to know them from its official documentation. That’s all in this article.

Thank you :)

References

https://stackoverflow.com/questions/31256252/why-does-numpy-linalg-solve-offer-more-precise-matrix-inversions-than-numpy-li

https://numpy.org/doc/stable/

https://numpy.org/doc/stable/reference/routines.linalg.html

3rd year CSE student at IIITKALYANI , enthusiastic learner and explorer

## More from Sweta Barnwal

3rd year CSE student at IIITKALYANI , enthusiastic learner and explorer