Say I have two lists containing vector:
A = [(1,1,1), (0,1,1)]
B = [(1,0,1), (1,0,0)]
I hope to perform dot product between each vector elementwise so that the output is
C = [2, 0]
How can I do this in python?
The fastest method here is using einsum
out = numpy.einsum('ij, ij->i', A, B)
It outperforms the multiply-add version by a factor of 2; the list comprehension version is a few hundred times slower.
Code to reproduce the plot:
import numpy
import perfplot
perfplot.show(
setup=lambda n: (numpy.random.rand(n, 3), numpy.random.rand(n, 3)),
kernels=[
lambda data: numpy.einsum("ij, ij->i", data[0], data[1]),
lambda data: numpy.multiply(data[0], data[1]).sum(1),
lambda data: [
sum(ai * bi for ai, bi in zip(a, b)) for a, b in zip(data[0], data[1])
],
],
labels=["einsum", "multiply+sum", "sum+zip"],
n_range=[2 ** k for k in range(18)],
xlabel="len(a)",
)
In pure Python, try a nested list/generator comprehension:
>>> [sum(ai * bi for ai, bi in zip(a, b))
... for a, b in zip(A, B)]
[2, 0]
or with numpy, you can do an element-wise product of the 2-dimensional arrays, followed by a sum along each row:
>>> import numpy as np
>>> np.multiply(A, B).sum(1)
array([2, 0])
Note that the numpy solution will only work if all vectors are the same length – each list of vectors is implicitly converted into a two-dimensional matrix.
We can use zipping, summing, and list comprehensions for a fancy one-liner:
A = [(1,1,1), (0,1,1)]
B = [(1,0,1), (1,0,0)]
C = [sum(i*j for i, j in zip(a, b)) for a, b in zip(A, B)]
print(C) # [2, 0]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With