Efficient NumPy Array Multiplication Operations

NumPyNumPyBeginner
Practice Now

Introduction

NumPy is a powerful library for scientific computing in Python. One of the most important features of NumPy is its ability to perform various types of array multiplications efficiently.

In this tutorial, we will explore the different multiplication operations available in NumPy, including numpy.multiply, numpy.dot, numpy.matmul, *, and @ operators.

Getting Started

Before we dive into the different multiplication operations in NumPy, let's first open the Python shell by typing the following command in the terminal.

python3

then import the library and create some sample arrays that we can use for demonstration.

import numpy as np

## Creating sample arrays
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])

We have created two arrays A and B, each with two rows and two columns. Now, let's explore the different multiplication operations available in NumPy.

numpy.multiply

The numpy.multiply function performs element-wise multiplication between two arrays. The two arrays must have the same shape. The resulting array will have the same shape as the input arrays.

C = np.multiply(A, B)

print(C)
## Output:
## array([[ 5, 12],
##       [21, 32]])

In this example, each element in A is multiplied with the corresponding element in B, resulting in the element-wise multiplication of the two arrays.

numpy.dot

The numpy.dot function performs matrix multiplication between two arrays. The first array must have the same number of columns as the second array has rows. The resulting array will have the same number of rows as the first array and the same number of columns as the second array.

C = np.dot(A, B)

print(C)
## Output:
## array([[19, 22],
##        [43, 50]])

In this example, we have performed matrix multiplication between arrays A and B. The resulting array C has two rows and two columns, as expected.

numpy.matmul

The numpy.matmul function also performs matrix multiplication between two arrays, but it has slightly different rules for handling multidimensional arrays. The two arrays must have the same shape, except for the last two dimensions, which must conform. If either array is 1-D, it is promoted to a matrix by appending a 1 to its shape.

C = np.matmul(A, B)

print(C)
## Output:
## array([[19, 22],
##        [43, 50]])

In this example, we get the same result as with numpy.dot. This is because our arrays A and B have the same shape, so numpy.matmul behaves the same way as numpy.dot.

And there is another different example:

## define two 3-D arrays
a = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
b = np.array([[[9, 10], [11, 12]], [[13, 14], [15, 16]]])

c = np.matmul(a, b)
d = np.dot(a, b)

print(c)
## Output:
## array([[[ 31,  34],
##        [ 71,  78]],
##        [[155, 166],
##        [211, 226]]])

print(d)
## Output:
## array([[[[ 31,  34],
##         [ 43,  46]],
##        [[ 71,  78],
##         [ 99, 106]]],
##       [[[111, 122],
##         [155, 166]],
##        [[151, 166],
##         [211, 226]]]])

In this example, numpy.matmul performs the batch matrix multiplication operation.

Since both a and b are 3-D arrays, the output of numpy.dot will have dimensionality (2,2,2,2). The first two dimensions correspond to the two batches of 2\times2 matrices in a and b. The next two dimensions correspond to the dot product of each pair of 2\times2 matrices in the batches:

## the first 2 × 2 result
dot(a[0], b[0]) =
dot([[1, 2],
 [3, 4]],
 [[9, 10],
 [11, 12]]
= [[1*9 + 2*11, 1*10 + 2*12],
   [3*9 + 4*11, 3*10 + 4*12]]
= [[31, 34],
   [43, 46]]

* operator

The * operator also performs element-wise multiplication between two arrays, but it behaves slightly differently than numpy.multiply. If the two arrays have the same shape, the * operator will perform element-wise multiplication, just like numpy.multiply. However, if one of the arrays is a scalar value, the * operator will perform scalar multiplication on every element of the other array.

C = A * B
D = A * 2

print(C)
## Output:
#array([[ 5, 12],
##       [21, 32]])

print(D)
## Output:
## array([[2, 4],
##       [6, 8]])

In the first example, we get the same result as with numpy.multiply. In the second example, we perform scalar multiplication on every element of array A.

@ operator

The @ operator performs matrix multiplication, just like numpy.dot and numpy.matmul. It was introduced in Python 3.5 as a shorthand for numpy.matmul.

C = A @ B

print(C)
## Output:
## array([[19, 22],
##       [43, 50]])

In this example, we use the @ operator to perform matrix multiplication between arrays A and B. The resulting array C has two rows and two columns, just like with numpy.dot and numpy.matmul.

Summary

In this tutorial, we have explored the different multiplication operations available in NumPy. Each of these operations has its own rules and use cases, so it's important to choose the right one for your specific task. By mastering these operations, you can efficiently perform array and matrix multiplications in Python using NumPy.

Other NumPy Tutorials you may like