How to Perform Matrix Operations with NumPy

How to Perform Matrix Operations with NumPy
Photo by Vlado Paunovic

NumPy is a powerful Python library that contains a large collection of mathematical functions, and supports the creation of matrices and multi-dimensional arrays to which these mathematical functions can be applied.

In this short tutorial, you will learn how to perform several of the most basic matrix operations with NumPy.

Matrices and Arrays in NumPy

In NumPy, a matrix is defined as a specialised array that is strictly 2-dimensional, and which retains its 2-dimensionality following the application of mathematical operations. A matrix of this type can be implemented using the np.matrix class, however NumPy no longer recommends use of this class as it may be removed in the future. The alternative option that is recommended by NumPy is to use the N-dimensional array type, ndarray.

The key difference between an ndarray and a matrix in NumPy is that the former can be of any dimensionality, and its use is not restricted to 2-dimensional operations.

Hence, in this tutorial we shall be focusing on implementing several basic matrix operations on 2-dimensional arrays, created using np.ndarray

Creating NumPy Arrays

Let’s first import the NumPy package and then proceed to create two, 2-dimensional arrays that are composed of two rows and three columns each. These arrays will be used in the ensuing examples of this tutorial:

# Import NumPy package  import numpy as np    # Create arrays  a1 = np.array([[0, 1, 0], [2, 3, 2]])  a2 = np.array([[3, 4, 3], [5, 6, 5]])  

The shape attribute lets us confirm the array’s dimensions:

# Print one of the arrays  print('Array 1:', 'n', a1, 'n Shape: n’, a1.shape)  

Output:

Array 1:   [[0 1 0]  [2 3 2]]    Shape: (2, 3)  

Basic Array Operations

NumPy provides its own functions to perform element-wise addition, subtraction, division and multiplication of arrays. In addition, Numpy also leverages Python’s arithmetic operators by extending their functionality to handle element-wise array operations.

Let’s start with element-wise addition between the arrays a1 and a2 as an example.

Element-wise addition of two arrays can be achieved by making use of the np.add function or the overloaded + operator:

# Using np.add  func_add = np.add(a1, a2)    # Using the + operator  op_add = a1 + a2  

By printing out the results, it may be confirmed that they both produce the same output:

# Print results  print('Function: n', func_add, 'nn', 'Operator: n', op_add)  

Output:

Function:   [[3 5 3]  [7 9 7]]    Operator:   [[3 5 3]  [7 9 7]]  

However, if we had to time them, we can notice a small difference:

import numpy as np  import timeit    def func():    a1 = np.array([[0, 1, 0], [2, 3, 2]])  a2 = np.array([[3, 4, 3], [5, 6, 5]])  np.add(a1, a2)    def op():    a1 = np.array([[0, 1, 0], [2, 3, 2]])  a2 = np.array([[3, 4, 3], [5, 6, 5]])  a1 + a2    # Timing the functions over 100000 iterations  func_time = timeit.timeit(func, number=100000)  op_time = timeit.timeit(op, number=100000)    # Print timing results  print('Function:', func_time, 'n', 'Operator:', op_time)  

Output:

Function: 0.2588757239282131   Operator: 0.24321464297827333  

Here it may be seen that the NumPy np.add function performs slightly slower than the + operator. This is mainly because the add function introduces type-checking to convert any array_like inputs (such as lists) into arrays before performing the addition operation. This, in turn, introduces an extra computational overhead over the + operator.

However, such measure also makes the np.add function less prone to error. For instance, applying np.add to inputs of type list still works (e.g. np.add([1, 1], [2, 2])), whereas applying the + operator results in list concatenation.

Similarly for element-wise subtraction (using np.subtract or -), division (using np.divide or /) and multiplication (using np.multiply or *), the NumPy functions perform type-checking, introducing a small computational overhead.

Several other operations that may come in handy include transposing and multiplying arrays.

Matrix transposition results in an orthogonal rotation of the matrix, and can be achieved using the np.transpose function (which includes type-checking) or the .T attribute:

# Using np.transpose  func_a1_T = np.transpose(a1)    # Using the .T attribute  att_a1_T = a1.T  

Matrix multiplication can be performed using the np.dot function or the @ operator (the latter implements the np.matmul function from Python 3.5 onwards):

# Using np.dot  func_dot = np.dot(func_a1_T, a2)    # Using the @ operator  op_dot = func_a1_T @ a2  

When working with 2-dimensional arrays, np.dot and np.matmul perform identically and both include type-checking.

Additional Resources

  • NumPy Array Objects
  • A Gentle Introduction to NumPy Arrays in Python

Stefania Cristina, PhD, is a Senior Lecturer with the Department of Systems and Control Engineering at the University of Malta. Her research interests lie within the domains of computer vision and machine learning.

More On This Topic

  • How to Perform Memory-Efficient Operations on Large Datasets with Pandas
  • Vector and Matrix Norms with NumPy Linalg Norm
  • Elevate Math Efficiency: Navigating Numpy Array Operations
  • Sparse Matrix Representation in Python
  • Idiot's Guide to Precision, Recall, and Confusion Matrix
  • Visualizing Your Confusion Matrix in Scikit-learn
0 0 votes
Article Rating
Subscribe
Notify of
guest
0 comments
Oldest
New Most Voted
Inline Feedbacks
View all comments