Python:两个向量列表中每个向量的点积

时间:2016-06-07 04:45:00

标签: python

假设我有两个包含vector的列表:

A = [(1,1,1), (0,1,1)]
B = [(1,0,1), (1,0,0)]

我希望在每个向量元素之间执行点积,以便输出

C = [2, 0]

我怎么能在python中做到这一点?

7 个答案:

答案 0 :(得分:4)

在纯Python中,尝试嵌套列表/生成器理解:

>>> [sum(ai * bi for ai, bi in zip(a, b))
...  for a, b in zip(A, B)]
[2, 0]

或者使用numpy,你可以做二维数组的元素乘积,然后沿着每一行求和:

>>> import numpy as np
>>> np.multiply(A, B).sum(1)
array([2, 0])

请注意,numpy解决方案仅在所有向量长度相同时才起作用 - 每个向量列表都隐式转换为二维矩阵。

答案 1 :(得分:4)

这里最快的方法是使用How to concatenate ranges in Google spreadsheets

out = numpy.einsum('ij, ij->i', A, B)

它比乘法加法版本优于2倍;列表理解版本几百次次。

einsum

重现情节的代码:

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)",
    logx=True,
    logy=True,
)

答案 2 :(得分:1)

我们可以使用压缩,求和和列表推导来制作一个花哨的单行:

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]

答案 3 :(得分:0)

试试这个:

[sum([y*z for y, z in zip(*x)]) for x in zip(A, B)]

这会产生:

[2, 0]

答案 4 :(得分:0)

def dot_product(vector_a, vector_b):
    vector_c = (vector_a[0]*vector_b[0],vector_a[1]*vector_b[1],vector_a[2]*vector_b[2]) #vector multiplication
    return sum(vector_c) #sum of each chord in the new vector
c = [dot_product(a[0],a[1]), dot_product(b[0],b[1])]

答案 5 :(得分:0)

使用 numpy.dot

dots_prods = [numpy.dot(a, b) for a,b in zip(list1, list2)]

但是,与@nico-schlömer 的 einsum 方法相比仍然很慢:

enter image description here

答案 6 :(得分:-1)

你可以使用numpy: http://docs.scipy.org/doc/numpy/reference/

import numpy
dtprd = numpy.dot(...)

另见: What is the pythonic way to calculate dot product?