Enable Dark Mode!
python-numpy-tutorial-2024.jpg
By: Arwa VV

Python NumPy Tutorial – 2024

Technical

NumPy, which stands for Numerical Python, is an essential Python library that supports matrices, arrays and various mathematical operations for effectively manipulating these data structures.
In this blog, we’ll discuss NumPy and its key features.
In Python, lists can be used in place of arrays, although they process data slowly. We use NumPy in place of Python lists because it is faster than Python lists. With NumPy, an array object can be created up to 50 times faster than with conventional Python lists. NumPy arrays are relatively efficient to access and modify because, unlike lists, they are kept in memory continuously. This is the reason why NumPy is faster than Python lists. The array object in NumPy is called ndarray.
To install NumPy, run the below command:
pip install numpy
We can create a NumPy array as following:
import numpy
arr = numpy.array([1, 2, 3, 4, 5])
print(arr)    # Output : [1 2 3 4 5]
NumPy is usually imported under the np alias.
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
print(arr)    # Output : [1 2 3 4 5]
To the type of above array:
print(type(arr))
Output : <class ‘numpy.ndarray’>
We can pass a list, tuple or any array-like object into the array() method to create an ndarray.

Dimensions in Arrays:

In NumPy, arrays can have multiple dimensions, allowing you to represent data in a more structured way compared to Python's standard lists. 
0-D Arrays:
0-D arrays, or Scalars, are the elements in an array. Each value in an array is a 0-D array.
1-D Arrays:
A one-dimensional array is similar to a Python list. It consists of elements arranged in a single line. It can also be defined as an array that has 0-D arrays as its elements.
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
print(arr)    # Output: [1, 2, 3, 4, 5]
2-D Arrays:
A two-dimensional array is like a matrix, organized as rows and
columns. It can also be defined as an array that has 1-D arrays as its elements.
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr)    # Output: [[1, 2, 3], [4, 5, 6]]
3-D arrays:
An array that has 2-D arrays (matrices) as its elements is called 3-D array. NumPy allows arrays with more than two dimensions. These can represent data in multiple dimensions, such as 3D arrays or higher.
import numpy as np
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[1, 2, 3], [4, 5, 6]]])
print(arr)
Output:      [[[1 2 3]
       [4 5 6]]
                     [[1 2 3]
       [4 5 6]]]

ndim:

We can check the dimension of NumPy arrays using the attribute ndim. It will return
an integer that indicates how many dimensions the array has.
import numpy as np
a = np.array(20)
b = np.array([1, 2, 3, 4])
c = np.array([[1, 2, 3], [4, 5, 6]])
print(a.ndim)        # Output: 0
print(b.ndim)        # Output: 1
print(c.ndim)        # Output: 2

ndmin:

To create an array with your desired specific number of dimension, you can use the ndmin argument as follows:
import numpy as np
arr = np.array([1, 2, 3, 4], ndmin=4)
print(arr)     # Output: [[[[1 2 3 4]]]]
print('dimensions :', arr.ndim)     # Output: 4
Array Indexing:
You can access an array element by referring to its index number
import numpy as np
arr = np.array([1, 2, 3, 4])
print(arr[0], arr[1], arr[2])     # Output: 1 2 3
To access 2-D array element:
import numpy as np
arr = np.array([[1,2,3,4,5], [6,7,8,9,10]])
print('2nd element on 1st row: ', arr[0, 1])
print('5th element on 2nd row: ', arr[1, 4])
Output:
2nd element on 1st row:  2
5th element on 2nd row:  10
To access 3-D array element:
import numpy as np
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
print(arr[0, 1, 2])
Output: 6
In this case, [[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]] is a 3D array with two 2D arrays as its elements ( [[1, 2, 3], [4, 5, 6]] and [[7, 8, 9], [10, 11, 12]] ).
So, first as we selected index 0, we have the element [[1, 2, 3], [4, 5, 6]] 
Next, we selected index 1 in [[1, 2, 3], [4, 5, 6]], so we have the element [4, 5, 6].
In [4, 5, 6], we selected index 2, we have element 6 which is the final output.
To access an array from the end, we can use negative indexing
import numpy as np
arr1 =  np.array([1,2,3,4,5])
print('Last element in arr1: ', arr1[-1])
arr2 = np.array([[1,2,3,4,5], [6,7,8,9,10]])
print('Last element from 2nd dim in arr2: ', arr2[1, -1])
Output:
Last element in arr1:  5
Last element from 2nd dim in arr2:  10

Array Slicing:

In NumPy, extracting a section of an array by defining a range of indices along each dimension is referred to as array slicing. 
In place of an index, we pass a slice as [start : end].
We can also define the step, like this: [start:end:step].
If we don't give ‘start’ it’s considered 0.
If we don't give ‘end’ it’s considered the length of the array in that dimension.
If we don't pass step it's considered 1.
The result includes the start index, but excludes the end index.
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(arr[2:6])      # Output: [3 4 5 6]
Here the start index is 2, and the end index is 6. As we have not provided a step, step would be 1. So elements from index 2 to index 6  (not included) will be taken.
print(arr[2:8:2])    # Output: [3 5 7]
In this case, the start index is 2, the end index is 8 and the step is 2, meaning every second element within the specified range will be included.
print(arr[4:])      # Output: [ 5  6  7  8  9 10]
In this case, elements from index 4 to the end of the array are sliced.
print(arr[:4])      # Output: [1 3 5 7]
In this case, elements from the beginning to index 4 (not included) are sliced.
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7])
print(arr[::2])     # Output: [1 3 5 7]
Slicing 2D array:
import numpy as np
arr = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
print(arr[0, 1:4])   # Output: [2 3 4]
Here, as we selected 0, we have the element [1, 2, 3, 4, 5]. From this, elements from index 1 to index 4  (not included) will be taken.
import numpy as np
arr = np.array([[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]])
print(arr[0:2, 1:4])
Here, from both elements, slice index 1 to index 4 (not included), this will return a 2-D array.
Copy vs View:
In NumPy, "copy" and "view" affect how data is managed and modified, particularly when dealing with large datasets. The distinction between a copy and a view lies in how NumPy handles memory allocation and references to the original data.
Copy creates a new array that is completely independent of the original array. Modifications to the copied array do not affect the original data.
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
arr_copy = arr.copy()
arr_copy[0] = 10
print(arr_copy)  # Output: [10, 2, 3, 4, 5]
print(arr)       # Output: [1, 2, 3, 4, 5]
View creates a new array object that references the same data as the original array. Modifications to the view affect the original data as well.
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
arr_view = arr.view()
arr_view[0] = 10
print(arr_view)  # Output: [10, 2, 3, 4, 5]
print(arr)       # Output: [10, 2, 3, 4, 5]
You can check whether an array is a copy or a view using the base attribute. If an array is a view, its base attribute will refer to the original array.
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
arr_view = arr.view()
arr_copy = arr.copy()
print(arr_view.base)  # Output: [1 2 3 4 5]
print(arr_copy.base)  # Output: None

Shape:

In NumPy,  the shape of an array refers to the array’s dimensions or structure, indicating the number of elements along each axis. The shape of a NumPy array is described by a tuple of integers, where each integer represents the size of a particular dimension.
import numpy as np
arr_2d = np.array([[1, 2, 3], [4, 5, 6]])
print(arr_2d.shape)  # Output: (2, 3) - 2 rows, 3 columns

Reshape:

Reshaping arrays in NumPy refers to changing the dimensions or structure of an array while maintaining the total number of elements. This operation allows you to alter the shape of the array without changing the data it contains.
Reshape from 1D to 2D:
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
newarr = arr.reshape(4, 3)
print(newarr)
#Output:
[[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]
The outermost dimension will have 4 arrays, each with 3 elements
Reshape From 1-D to 3-D:
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
newarr = arr.reshape(2, 3, 2)
print(newarr)
# Output:
[[[ 1  2]
  [ 3  4]
  [ 5  6]]
 [[ 7  8]
  [ 9 10]
  [11 12]]]
The outermost dimension will have 2 arrays that contain 3 arrays, each with 2 elements.

Array Iterating:

Using Loops:
For Loop:
Iterating through a NumPy array using a basic for loop is straightforward:
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
for element in arr:
    print(element)
# Output:
1
2
3
4
5
Iterating through Multidimensional Arrays:
For multidimensional arrays, nested loops are used to access elements.
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
for row in arr:
    for element in row:
        print(element)
# Output:
1
2
3
4
5
6

Using NumPy Functions:

nditer():

The nditer() function allows efficient iteration through arrays, especially for multidimensional arrays.
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
for element in np.nditer(arr):
    print(element)
# Output:
1
2
3
4
5
6

Joining Arrays:

In NumPy, you can join or concatenate arrays using functions like np.concatenate(), np.vstack() (vertical stack), np.hstack() (horizontal stack), np.dstack() (depth stack), etc.
Here are examples of how to use these functions:
np.concatenate() joins a sequence of arrays along an existing axis.
import numpy as np
array1 = np.array([[1, 2, 3], [4, 5, 6]])
array2 = np.array([[7, 8, 9], [10, 11, 12]])
# Concatenating along axis 0 (rows)
result_concat_axis0 = np.concatenate((array1, array2), axis=0)
print("Concatenated along axis 0:\n", result_concat_axis0)
# Concatenating along axis 1 (columns)
result_concat_axis1 = np.concatenate((array1, array2), axis=1)
print("\nConcatenated along axis 1:\n", result_concat_axis1)
Output:
Concatenated along axis 0:
 [[ 1  2  3]
 [ 4  5  6]
 [ 7  8  9]
 [10 11 12]]
Concatenated along axis 1:
 [[ 1  2  3  7  8  9]
 [ 4  5  6 10 11 12]]
np.vstack() and np.hstack() stack arrays vertically and horizontally, respectively.
import numpy as np
array1 = np.array([[1, 2],
                   [3, 4]])
array2 = np.array([[5, 6],
                   [7, 8]])
# Vertical stacking
result_vstack = np.vstack((array1, array2))
print("Vertically stacked arrays:\n", result_vstack)
# Horizontal stacking
result_hstack = np.hstack((array1, array2))
print("\nHorizontally stacked arrays:\n", result_hstack)
Output:
Vertically stacked arrays:
 [[1 2]
 [3 4]
 [5 6]
 [7 8]]
Horizontally stacked arrays:
 [[1 2 5 6]
 [3 4 7 8]]
np.dstack() stacks arrays along the third axis (depth).
import numpy as np
array1 = np.array([[1, 2],
                   [3, 4]])
array2 = np.array([[5, 6],
                   [7, 8]])
# Depth stacking
result_dstack = np.dstack((array1, array2))
print("Depth stacked arrays:\n", result_dstack)
Output:
Depth stacked arrays:
 [[[1 5]
  [2 6]]
 [[3 7]
  [4 8]]]

Array Splitting:

In NumPy, you can split arrays into multiple smaller arrays using functions like np.split(), np.array_split(), np.vsplit() (vertical split), np.hsplit() (horizontal split), np.dsplit() (depth split), etc.
np.split() splits an array into multiple sub-arrays along a given axis.
import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
# Splitting the array into 3 equal parts along axis 0
result_split = np.split(arr, 3)
print(result_split)
Output:
[array([1, 2, 3]), array([4, 5, 6]), array([7, 8, 9])]
Unlike np.split(), np.array_split() allows splitting arrays into unequal parts.
import numpy as np
arr = np.arange(10)
result_array_split = np.array_split(arr, 4)
print(result_array_split)
Output:
[array([0, 1, 2]), array([3, 4, 5]), array([6, 7]), array([8, 9])]
np.vsplit() and np.hsplit() split arrays vertically and horizontally, respectively.
import numpy as np
arr = np.array([[1, 2, 3],
                [4, 5, 6],
                [7, 8, 9],
                [10, 11, 12]])
# Vertical splitting into 2 parts
result_vsplit = np.vsplit(arr, 2)
print("Vertically split:\n", result_vsplit)
# Horizontal splitting into 3 parts
result_hsplit = np.hsplit(arr, 3)
print("\nHorizontally split:\n", result_hsplit)
Output:
Vertically split:
 [array([[1, 2, 3],[4, 5, 6]]), 
  array([[ 7,  8,  9],[10, 11, 12]])]
Horizontally split:
 [array([[ 1],
       [ 4],
       [ 7],
       [10]]),
 array([[ 2],
       [ 5],
       [ 8],
       [11]]), 
array([[ 3],
       [ 6],
       [ 9],
       [12]])]
np.dsplit() splits arrays along the third axis (depth).
import numpy as np
arr = np.array([[[1, 2],
                 [3, 4]],
                
                [[5, 6],
                 [7, 8]]])
# Depth splitting
result_dsplit = np.dsplit(arr, 2)
print("Depth split:\n", result_dsplit)
Output:
Depth split:
 [array([[[1], [3]], [[5], [7]]]), 
  array([[[2],[4]], [[6],[8]]])]

Searching in Arrays:

In NumPy, you can perform searching operations on arrays to find specific elements or indices using functions like np.where(), np.searchsorted(), np.nonzero(), np.extract().
np.where() returns the indices of elements in an array that satisfy a given condition.
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
# Find indices where elements are greater than 2
indices = np.where(arr > 2)
print(indices)     # Output: (array([2, 3, 4]),)
np.searchsorted() finds the indices at which elements should be placed in order to maintain order in a sorted array.
import numpy as np
arr = np.array([1, 3, 5, 7, 9])
# Find indices where 6 should be inserted to maintain sorted # order
index = np.searchsorted(arr, 6)
print(index)       # Output: 3
np.nonzero() returns the indices of elements that are non-zero.
import numpy as np
arr = np.array([0, 2, 0, 4, 0, 6])
# Find indices of non-zero elements
indices = np.nonzero(arr)
print(indices)       # Output: (array([1, 3, 5]),)
np.extract() returns elements from an array that satisfy a specified condition.
import numpy as np
arr = np.array([1, 2, 3, 4, 5])
# Extract elements that are greater than 2
result = np.extract(arr > 2, arr)
print(result)       # Output:  [3 4 5]

Array Sorting:

In NumPy, you can sort arrays using various functions available in the library. Here are some commonly used methods for sorting NumPy arrays:
np.sort() returns a sorted copy of an array along a specified axis.
import numpy as np
arr = np.array([3, 1, 5, 2, 4])
sorted_arr = np.sort(arr)
print(sorted_arr)  # Output: [1 2 3 4 5]
In case of 2D array:
import numpy as np
arr = np.array([[3, 2, 4], [5, 0, 1]])
print(np.sort(arr))
Output:
[[2 3 4]
        [0 1 5]]
np.argsort() returns the indices that would sort an array.
import numpy as np
arr = np.array([3, 1, 5, 2, 4])
indices = np.argsort(arr)
print(indices)  # Output: [1 3 0 4 2]
These are some of the key features of NumPy. We will discuss the NumPy random and NumPy ufuncs in another blog.  In conclusion, NumPy stands as a powerhouse for handling numerical operations and large datasets in Python. Its efficiency in array operations, mathematical functions, and data manipulation makes it a go-to library for scientific computing, machine learning, and data analysis applications.


If you need any assistance in odoo, we are online, please chat with us.



0
Comments



Leave a comment



whatsapp_icon
location

Calicut

Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635

location

Kochi

Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.

location

Bangalore

Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message