Advanced Topics
Linear algebra operations
This is an advanced topics tutorial.
NumPy is a powerful library in Python for numerical computing, especially when it comes to linear algebra operations. The following are some common linear algebra operations. Within this section, we cover: matrix multiplication, matrix transpose, matrix inversion, determinant, eigenvalues and eigenvectors, solving linear equations, and matrix decompositions.
Matrix multiplication
NumPy provides “np.dot()” or the “@” operator for matrix multiplication.
import numpy as np # matrices matrix_1 = np.array([[1, 2], [3, 4]]) matrix_2 = np.array([[5, 6], [7, 8]]) # dot method result_dot = np.dot(matrix_1, matrix_2) # @ method result_at_operator = matrix_1 @ matrix_2 print(result_dot) print(result_at_operator)
# Outcome for both methods [[19 22] [43 50]]
Matrix transpose
Transposing a matrix swaps its rows and columns. Two methods: “np.transpose()” or “T” attribute.
import numpy as np # matrix matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # transpose method transpose_matrix = np.transpose(matrix) # T attribute method transpose_matrix_alt = matrix.T print(transpose_matrix) print(transpose_matrix_alt)
# Outcome for both methods [[1 4 7] [2 5 8] [3 6 9]]
Matrix inversion
NumPy’s “np.linalg.inv()” function calculates the inverse of a matrix.
import numpy as np # matrix matrix = np.array([[1, 2], [3, 4]]) # inverse method inverse_matrix = np.linalg.inv(matrix) print(inverse_matrix)
# Outcome [[-2. 1. ] [ 1.5 -0.5]]
Determinant
NumPy’s “np.linalg.det()” function calculates the determinant of a matrix.
import numpy as np # matrix matrix = np.array([[1, 2], [3, 4]]) # determinant method determinant = np.linalg.det(matrix) print(determinant) # Outcome: -2.0000000000000004
Eigenvalues and Eigenvectors
NumPy’s “np.linalg.eig()” function computes the eigenvalues and eigenvectors of a matrix.
import numpy as np # matrix matrix = np.array([[1, 2], [2, 1]]) # eigenvalues and eigenvectors methods eigenvalues, eigenvectors = np.linalg.eig(matrix) print(eigenvalues) print(eigenvectors)
# eigenvalues [ 3. -1.] # eigenvectors [[ 0.70710678 -0.70710678] [ 0.70710678 0.70710678]]
Solving linear equations
NumPy’s “np.linalg.solve()” function can be used to solve systems of linear equations.
import numpy as np # coefficients matrix coefficients = np.array([[2, 1], [1, -1]]) # constants vector constants = np.array([5, 1]) # solve linear equations solution = np.linalg.solve(coefficients, constants) print(solution) # Outcome: [2. 1.]
Matrix decompositions
NumPy provides functions for matrix decompositions like Singular Value Decomposition (SVD), QR Decomposition, and Cholesky Decomposition.
We cover matrix decompositions separately, as there are three different methods.
Singular Value Decomposition (SVD)
import numpy as np # matrix matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # SVD U, S, V = np.linalg.svd(matrix) print(U) print(S) print(V)
# U outcome [[-0.21483724 0.88723069 0.40824829] [-0.52058739 0.24964395 -0.81649658] [-0.82633754 -0.38794278 0.40824829]] # S outcome [1.68481034e+01 1.06836951e+00 4.41842475e-16] # V outcome [[-0.47967118 -0.57236779 -0.66506441] [-0.77669099 -0.07568647 0.62531805] [-0.40824829 0.81649658 -0.40824829]]
QR Decomposition
import numpy as np # matrix matrix = np.array([[1, 2], [3, 4], [5, 6]]) # QR decomposition Q, R = np.linalg.qr(matrix) print(Q) print(R)
# Q outcome [[-0.16903085 0.89708523] [-0.50709255 0.27602622] [-0.84515425 -0.34503278]] # R outcome [[-5.91607978 -7.43735744] [ 0. 0.82807867]]
Cholesky Decomposition
import numpy as np # matrix matrix = np.array([[4, 12, -16], [12, 37, -43], [-16, -43, 98]]) # Cholesky decomposition L = np.linalg.cholesky(matrix) print(L)
# Outcome [[ 2. 0. 0.] [ 6. 1. 0.] [-8. 5. 3.]]
Working with structured arrays
Homogeneous refers to data of the same type, whereas heterogeneous refers to diverse data (data containing different types).
Working with structured arrays in NumPy allows you to handle data with multiple fields or columns, similar to a table or database. Structured arrays provide a way to store and manipulate heterogeneous data efficiently. In other words, structured arrays allow the handling diverse data.
Creating structured arrays
To create a structured array, specify the data types for each field/column. You can use a list of tuples where each tuple represents a field.
import numpy as np # Data types for structured array dtype = [('name', 'S10'), ('age', int), ('weight', float)] # Sample structured array data = np.array([('Martin', 28, 67.2), ('Kane', 30, 58.3)], dtype=dtype)
Let’s see the data types outcome.
print(data.dtype) # Outcome: [('name', 'S10'), ('age', '<i4'), ('weight', '<f8')]
S10 refers to a string data type (with length 10). i4 refers to a 4-byte integer data type. And f8 refers to 8-byte float data type.
Accessing data
To access data within the structured array, use the field names.
# Accessing data print(data['name']) print(data['age']) print(data['weight']) # Output: [b'Martin' b'Kane'] # Output: [28 30] # Output: [67.2 58.3]
Iterating over rows
To iterate over rows of the structured array, use a loop.
# Iterating over rows for row in data: print(row) # Output: (b'Martin', 28, 67.2) # Output: (b'Kane', 30, 58.3)
Filtering data
To filter the structured array, use conditional signs.
# Filtering data filtered_data = data[data['age'] > 29] print(filtered_data) # Output: [(b'Kane', 30, 58.3)]
Adding and removing records
To add or remove records from the structured array, use “append” and “delete“.
# New array record new_record = np.array(('Patrick', 18, 63.1), dtype=dtype) # Append record data = np.append(data, new_record) print(data) # Output: [(b'Martin', 28, 67.2) (b'Kane', 30, 58.3) (b'Patrick', 18, 63.1)] # Delete last record data = np.delete(data, -1) print(data) # Output: [(b'Martin', 28, 67.2) (b'Kane', 30, 58.3)]
Sorting
To sort the structured array, use the “sort” method.
print(data) # Output: [(b'Martin', 28, 67.2) (b'Kane', 30, 58.3)] # Sorting by weight data.sort(order='weight') print(data) # Output: [(b'Kane', 30, 58.3) (b'Martin', 28, 67.2)]
Concatenating
To concatenate multiple structured arrays, use the “concatenate” method.
# Concatenating arrays new_array = np.array([('Eve', 35, 65.0)], dtype=dtype) concatenated_data = np.concatenate((data, new_array)) print(concatenated_data) # Output: [(b'Kane', 30, 58.3) (b'Martin', 28, 67.2) (b'Eve', 35, 65. )]
Loading and saving data with NumPy
NumPy provides functions to load and save data from/to files. These functions support various file formats such as text files and NumPy’s own “.npy” format. Let’s dive into it.
Saving data
Text
import numpy as np # Sample data data = np.array([[1, 2, 3], [4, 5, 6]]) # Save data to a text file np.savetxt('data.txt', data, delimiter=',')
Binary
import numpy as np # Sample data data = np.array([[1, 2, 3], [4, 5, 6]]) # Save data to a binary file np.save('data.npy', data)
Multiple arrays
import numpy as np # Sample data array1 = np.array([1, 2, 3]) array2 = np.array([4, 5, 6]) # Save multiple arrays to a single file np.savez('multiple_arrays.npz', array1=array1, array2=array2)
Loading data
Text
import numpy as np # Load data from a text file data = np.loadtxt('data.txt', delimiter=',') print(data) #Output: [[1. 2. 3.] #Output: [4. 5. 6.]]
Binary
import numpy as np # Load data from a binary file data = np.load('data.npy') print(data) #Output: [[1 2 3] #Output: [4 5 6]]
Multiple arrays
import numpy as np # Load multiple arrays from a single file loaded_data = np.load('multiple_arrays.npz') array1 = loaded_data['array1'] array2 = loaded_data['array2'] print(array1) print(array2) #Output: [1 2 3] #Output: [4 5 6]
This is an original advanced topics educational material created by aicorr.com.
Next: Advanced Topics