Introduction to NumPy(Part-I)

In this article, we will learn about Introduction to NumPy.

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

Linux users can follow the steps mentioned in the link.

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.dtype
dtype('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)
>>>array
array([[ 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 zerosand 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.

To learn more I am leaving a link to the website.

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 np
y = 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[9] # output: 8
>>>arr.reshape(2,5)
>>>arr
array([[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])
>>> A
array([[1, 2, 3],
[4, 5, 6]])
>>> B
array([7, 8, 9])
>>> A.shape
(2, 3)
>>> B.shape
(3,)
>>> A.T
array([[1, 4],
[2, 5],
[3, 6]])
>>>
>>> B.T
array([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]])
>>> A
array([[1, 2],
[3, 4]])
>>> b = np.array([10, 20])
>>> b
>>> x = solve(A,b)
>>> x
array([ 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]])
>>> arr
array([[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