NumPy - Array Multiplication

NumPy Array Multiplication

NumPy array multiplication refers to the process of multiplying two arrays element-wise. In this context, element-wise multiplication means that each element in one array is multiplied by the corresponding element in the other array.

The result is a new array where each element represents the product of the corresponding elements from the input arrays.

Element-wise Multiplication in NumPy

Element-wise multiplication, also known as Hadamard product, is an operation in NumPy where two arrays of the same shape are multiplied together, and the operation is applied to each corresponding pair of elements.

For element-wise multiplication to be performed, the two arrays must have the same shape. If the arrays are of different shapes, broadcasting rules are applied to make them compatible.

Example

In the following example, we are multiplying each element of array a by the corresponding element of array b

import numpy as np

# Creating two arrays
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])

# Performing element-wise multiplication
result = a * b
print(result)

Following is the output obtained −

[ 4 10 18]

Multiplying by a Scalar in NumPy

Scalar multiplication refers to multiplying every element of an array by a single scalar value. Each element in the array is multiplied by the scalar value, resulting in a new array where all elements are scaled accordingly.

The shape of the resulting array is the same as the original array, but each element is scaled by the scalar.

Example

In this example, we are multiplying the scalar “3” with each element of the array “a” −

import numpy as np

# Creating an array
a = np.array([1, 2, 3])

# Multiplying by a scalar
result = a * 3
print(result)

This will produce the following result −

[3 6 9]

Multiplying NumPy Arrays of Different Shapes

When multiplying arrays of different shapes, NumPy uses broadcasting to make the shapes compatible for element-wise operations. Broadcasting aligns dimensions from the rightmost side, adjusts shapes according to specific rules, and performs the operation smoothly.

Example

In the example below, array “b” is broadcasted to match the shape of array “a”, and then element-wise multiplication is performed −

import numpy as np

# Creating arrays with different shapes
a = np.array([[1, 2, 3], [4, 5, 6]])
b = np.array([10, 20, 30])

# Multiplying arrays with broadcasting
result = a * b
print(result)

Following is the output of the above code −

[[10 40 90]
 [40 100 180]]

Matrix Multiplication in NumPy

Matrix multiplication is an operation in linear algebra where two matrices are multiplied according to specific rules. In NumPy, this operation is performed using the np.dot() function, the @ operator, or the np.matmul() function.

For matrix multiplication to be valid, the number of columns in the first matrix must be equal to the number of rows in the second matrix. If matrix A has shape (m, n) and matrix B has shape (n, p), the resulting matrix will have shape (m, p).

Example: Using numpy.dot() function

The np.dot() function in NumPy is used for calculating dot products of two arrays. It handles both matrix multiplication for 2D arrays and dot products for 1D arrays −

import numpy as np

# Define two matrices
matrix1 = np.array([[1, 2],
                    [3, 4]])

matrix2 = np.array([[5, 6],
                    [7, 8]])

# Perform matrix multiplication using np.dot
result = np.dot(matrix1, matrix2)
print(result)

The output obtained is as shown below −

[[19 22]
 [43 50]]

Example: Using the ”@” Operator

The @ operator in NumPy provides a shorthand for the np.dot() function. It performs matrix multiplication for 2D arrays and is used to calculate the dot product for 1D arrays −

import numpy as np

# Define the same matrices
matrix1 = np.array([[1, 2],
                    [3, 4]])

matrix2 = np.array([[5, 6],
                    [7, 8]])

# Perform matrix multiplication using the @ operator
result = matrix1 @ matrix2
print(result)

After executing the above code, we get the following output −

[[19 22]
 [43 50]]

Example: Using the np.matmul() Function

The np.matmul() function can handle arrays with more than two dimensions by performing matrix multiplication on the last two dimensions of the input arrays, with any preceding dimensions being broadcasted as needed −

import numpy as np

# Define a 3D array and a 2D array
array_3d = np.array([[[1, 2],
                      [3, 4]],

                     [[5, 6],
                      [7, 8]]])

array_2d = np.array([[1, 0],
                     [0, 1]])

# Perform matrix multiplication using np.matmul
result = np.matmul(array_3d, array_2d)
print(result)

The result produced is as follows −

[[[1 2]
  [3 4]]

  [[5 6]
  [7 8]]]

Element-wise vs. Matrix Multiplication

It is important to differentiate between element-wise multiplication (using *) and matrix multiplication (using @ or np.dot()) −

  • Element-wise Multiplication − Each element in the first array is multiplied by the corresponding element in the second array.
  • Matrix Multiplication − Performs a dot product of rows and columns, following linear algebra rules.

Example

In this example, we are highlighting the difference between element-wise multiplication and matrix multiplication −

import numpy as np

# Creating two 2D arrays
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])

# Element-wise multiplication
element_wise_result = a * b
print("Element-wise multiplication:\n", element_wise_result)

# Matrix multiplication
matrix_result = np.dot(a, b)
print("Matrix multiplication:\n", matrix_result)

We get the output as shown below −

Element-wise multiplication:
 [[ 5 12]
 [21 32]]
Matrix multiplication:
 [[19 22]
 [43 50]]

Multiplying Arrays with Different Data Types

When multiplying arrays with different data types in NumPy, type coercion rules are applied to ensure that the operation can be performed. This process involves converting the arrays to a common data type before performing the multiplication.

NumPy uses a set of promotion rules to determine the data type of the result. The general rule is to convert the operands to the type that can hold the result without losing precision. Following i the promotion order −

Boolean → Integer → Floating-point → Complex.

For example, integer and floating-point numbers are promoted to floating-point types to accommodate decimal values.

Example

In this case, NumPy promotes the integer array b to a float type to match the data type of array a

import numpy as np

# Creating arrays with different data types
a = np.array([1.5, 2.5, 3.5])
b = np.array([2, 3, 4], dtype=np.int32)

# Performing multiplication
result = a * b
print(result)

Following is the output obtained −

[3.  7.5 14.]

Handling Dimension Mismatch in Multiplication

When performing multiplication operations between arrays in NumPy, dimension mismatch can occur if the arrays do not share compatible shapes. NumPy addresses this issue through broadcasting and raises a ValueError in such case.

Example

In the following example, the shapes of “a” and “b” are not compatible for broadcasting, leading to an error −

import numpy as np

# Creating arrays with incompatible shapes
a = np.array([1, 2, 3])
b = np.array([[1, 2], [3, 4]])

# Attempting to multiply incompatible arrays
result = a * b
print(result)

The result produced is as follows −

Traceback (most recent call last):File "/home/cg/root/66a1de2fae52f/main.py", line 8, in <module>result = a * bValueError: operands could not be broadcast together with shapes (3,) (2,2) 
© 2024 All rights reserved. | Made With 🤍 By The_MAK Team