【问题标题】:What is the pythonic way to calculate dot product?计算点积的pythonic方法是什么?
【发布时间】:2011-05-07 06:32:55
【问题描述】:

我有两个列表,一个名为 A,另一个名为 B。A 中的每个元素都是三元组,B 中的每个元素都只是一个数字。我想计算定义为的结果:

结果 = A[0][0] * B[0] + A[1][0] * B[1] + ... + A[n-1][0] * B[n-1 ]

我知道逻辑很简单但是如何用pythonic方式编写?

谢谢!

【问题讨论】:

  • A 的结构方式是一个二维列表/矩阵。

标签: python dot-product


【解决方案1】:

Python 3.5 有一个显式运算符 @ 用于点积, 所以你可以写

a = A @ B

而不是

a = numpy.dot(A,B)

【讨论】:

  • 请参阅 stackoverflow.com/questions/45443562/… 以了解警告
  • 实际上,@ 操作符是 Numpy 的,而不是 Python 的
  • @WalterTross @ 是 Python 的,尽管它目前不使用它。 Numpy 在其数组中实现它。
  • 这就是为什么我写“而不是”而不是“,不是”;-)
  • @ 运算符专门用于矩阵乘法,因此 numpy 没有做任何事情:python.org/dev/peps/pep-0465(只是基础 Python 没有矩阵)
【解决方案2】:
import numpy
result = numpy.dot( numpy.array(A)[:,0], B)

http://docs.scipy.org/doc/numpy/reference/

如果你想在没有 numpy 的情况下这样做,请尝试

sum( [a[i][0]*b[i] for i in range(len(b))] )

【讨论】:

    【解决方案3】:

    我最喜欢的 Pythonic 点积是:

    sum([i*j for (i, j) in zip(list1, list2)])
    


    因此,对于您的情况,我们可以这样做:

    sum([i*j for (i, j) in zip([K[0] for K in A], B)])
    

    【讨论】:

    • 在求和之前构建整个列表
    【解决方案4】:
    from operator import mul
    
    sum(map(mul, A, B))
    

    【讨论】:

      【解决方案5】:

      使用操作符和 itertools 模块:

      from operator import mul
      from itertools import imap
      
      sum(imap(mul, A, B))
      

      【讨论】:

      【解决方案6】:

      使用实现dotproductitertools recipe的第三方库more_itertools

      import more_itertools as mit
      
      
      a = [1, 2, 3]
      b = [7, 8, 9]
      
      mit.dotproduct(a, b)
      # 50
      

      【讨论】:

        【解决方案7】:
        >>> X = [2,3,5,7,11]
        >>> Y = [13,17,19,23,29]
        >>> dot = lambda X, Y: sum(map(lambda x, y: x * y, X, Y))
        >>> dot(X, Y)
        652
        

        就是这样。

        【讨论】:

          【解决方案8】:

          对于这种事情,最 Pythonic 的方式可能是使用numpy。 ;-)

          【讨论】:

            【解决方案9】:

            人们将 @ 运算符重新指定为点积运算符。这是我使用 vanilla python 的 zip 的代码,它返回一个元组。然后使用列表推导而不是映射。

            def dot_product(a_vector,b_vector):
                #a1 x b1 + a2 * b2..an*bn return scalar
                return sum([an*bn for an,bn in zip(a_vector,b_vector)])
            
            X = [2,3,5,7,11]
            Y = [13,17,19,23,29]
            print(dot_product(X,Y)) #652
            
            a=[1,2,3]
            b=[4,5,6]
            print(dot_product(a,b)) #prints 32= 1*4 + 2*5 + 3*6 = 
            a = [1, 2, 3]
            b = [7, 8, 9]
            print(dot_product(a,b)) #prints 50 
            

            【讨论】:

              【解决方案10】:

              这可能是重复的解决方案,但是:

              >>> u = [(1, 2, 3), (4, 5, 6)]
              >>> v = [3, 7]
              

              简单的Python

              >>> sum([x*y for (x, *x2), y in zip(u,v)])
              31
              

              或使用numpy(如user57368 的回答中所述):

              import numpy as np
              >>> np.dot(np.array(u)[:,0], v)
              31
              

              【讨论】:

                【解决方案11】:

                以上所有答案都是正确的,但在我看来,计算点积最pythonic的方法是:

                >>> a=[1,2,3]
                >>> b=[4,5,6]
                >>> sum(map(lambda pair:pair[0]*pair[1],zip(a,b)))
                32
                

                【讨论】:

                  猜你喜欢
                  • 2014-02-20
                  • 1970-01-01
                  • 2014-05-22
                  • 1970-01-01
                  • 2020-11-20
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2020-02-13
                  相关资源
                  最近更新 更多