Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Numpy elementwise product of 3d array

I have two 3d arrays A and B with shape (N, 2, 2) that I would like to multiply element-wise according to the N-axis with a matrix product on each of the 2x2 matrix. With a loop implementation, it looks like

C[i] = dot(A[i], B[i])

Is there a way I could do this without using a loop? I've looked into tensordot, but haven't been able to get it to work. I think I might want something like tensordot(a, b, axes=([1,2], [2,1])) but that's giving me an NxN matrix.

like image 823
Remy Avatar asked Aug 12 '15 06:08

Remy


People also ask

Does NumPy do element-wise multiplication?

The NumPy library's np. multiply(x1, x2) method receives two matrices as input and executes element-wise multiplication over them before returning the resultant matrix. We must send the two matrices as input to the np. multiply() method to execute element-wise input.

Is NP multiply same as *?

There is no difference. However, the np. multiply function can take in additional, optional arguments, making it more versatile.

How element by element multiplication is is performed on NumPy arrays?

multiply() in Python. numpy. multiply() function is used when we want to compute the multiplication of two array. It returns the product of arr1 and arr2, element-wise.


1 Answers

It seems you are doing matrix-multiplications for each slice along the first axis. For the same, you can use np.einsum like so -

np.einsum('ijk,ikl->ijl',A,B)

We can also use np.matmul -

np.matmul(A,B)

On Python 3.x, this matmul operation simplifies with @ operator -

A @ B

Benchmarking

Approaches -

def einsum_based(A,B):
    return np.einsum('ijk,ikl->ijl',A,B)

def matmul_based(A,B):
    return np.matmul(A,B)

def forloop(A,B):
    N = A.shape[0]
    C = np.zeros((N,2,2))
    for i in range(N):
        C[i] = np.dot(A[i], B[i])
    return C

Timings -

In [44]: N = 10000
    ...: A = np.random.rand(N,2,2)
    ...: B = np.random.rand(N,2,2)

In [45]: %timeit einsum_based(A,B)
    ...: %timeit matmul_based(A,B)
    ...: %timeit forloop(A,B)
100 loops, best of 3: 3.08 ms per loop
100 loops, best of 3: 3.04 ms per loop
100 loops, best of 3: 10.9 ms per loop
like image 59
Divakar Avatar answered Oct 11 '22 14:10

Divakar