NumPy 点积:取向量积的积(而不是求和)

Posted

技术标签:

【中文标题】NumPy 点积:取向量积的积(而不是求和)【英文标题】:NumPy dot product: take product of vector products (rather than sum) 【发布时间】:2016-01-08 03:13:59 【问题描述】:

假设我有两个矩阵:M 是 2x3,C 是 3x4...

import numpy as np
M = np.matrix([ [1,2,3], [4,5,6]])
C = np.matrix([ [1,1,2,2], [1,2,1,2], [2,1,1,1]])

我需要将这些矩阵相乘以获得大小为 2x4 的结果。使用np.dot(M, C) 会很容易,但我想将向量乘积相乘而不是求和。

例如,一个普通的点积可以:

result[0,0] = (M[0,0]*C[0,0]) + (M[0,1]*C[1,0]) + (M[0,2]*C[2,0])
# result[0,0] = (1*1) + (2*1) + (3*2)
# result[0,0] = 9

我只是想用乘号替换加号...

result[0,0] = (M[0,0]*C[0,0]) * (M[0,1]*C[1,0]) * (M[0,2]*C[2,0])
# result[0,0] = (1*1) * (2*1) * (3*2)
# result[0,0] = 12

我最好的解决方案是循环遍历 M 的行 --

result = np.empty( (2,4) )
for i in range(2):
    result[i,:] = np.prod(np.multiply(np.tile(M[i,:].T , (1,4)), C) , axis=0)

打破这一点,M 的每一行都被转置,然后平铺(使用np.tile),因此它的大小与C 相同(即3x4)。然后我将矩阵元素相乘,并取每一列的乘积。

在我编写的实际程序中,MC 不一定是整数,可以是任意大小,并且这种计算要执行数千次。我想知道是否有人知道一种快速且易读的方法。

更新

@Warren Weckesser 提供了一个很好的解决方案。但是现在我有了一个新的挑战——具体来说,如果我想在向量乘积之前减去一个数字,然后再相乘怎么办?

这可以在我之前的解决方案中这样做:

result1 = np.empty( (2,4) ) 
for i in range(2): 
    result1[i,:] = np.prod( 1 - np.multiply( np.tile(M[i,:].T , (1,4)), C) , axis=0)

我玩过@Warren Weckesser 提供的解决方案,但无济于事。我绝对想找出更优雅的东西!

【问题讨论】:

【参考方案1】:

这是一个快速的方法:

In [68]: M
Out[68]: 
matrix([[1, 2, 3],
        [4, 5, 6]])

In [69]: C
Out[69]: 
matrix([[1, 1, 2, 2],
        [1, 2, 1, 2],
        [2, 1, 1, 1]])

In [70]: M.prod(axis=1) * C.prod(axis=0)
Out[70]: 
matrix([[ 12,  12,  12,  24],
        [240, 240, 240, 480]])

M.prod(axis=1)M 行中元素的乘积。因为Mmatrix 实例,所以结果的形状是(2, 1):

In [71]: M.prod(axis=1)
Out[71]: 
matrix([[  6],
        [120]])

同样,C.prod(axis=0)C 列下的乘积:

In [72]: C.prod(axis=0)
Out[72]: matrix([[2, 2, 2, 4]])

那么这两个矩阵的矩阵乘积,形状为 (2, 1) 和 (1, 4),形状为 (2, 4),它包含了你想要的乘积。

对于数组,使用prod()keepdims 参数来维护2D 形状,并使用dot() 方法代替*

In [79]: m = M.A

In [80]: c = C.A

In [81]: m
Out[81]: 
array([[1, 2, 3],
       [4, 5, 6]])

In [82]: c
Out[82]: 
array([[1, 1, 2, 2],
       [1, 2, 1, 2],
       [2, 1, 1, 1]])

In [83]: m.prod(axis=1, keepdims=True).dot(c.prod(axis=0, keepdims=True))
Out[83]: 
array([[ 12,  12,  12,  24],
       [240, 240, 240, 480]])

【讨论】:

这太棒了!谢谢。如果我想在相乘之前从向量积中减去一些东西,你有什么建议吗?即,结果 = np.empty( (2,4) ) for i in range(2): result[i,:] = np.prod( 1 - np.multiply(np.tile(M[i,:]. T , (1,4)), C) , 轴=0)

以上是关于NumPy 点积:取向量积的积(而不是求和)的主要内容,如果未能解决你的问题,请参考以下文章

Python Numpy中的几个矩阵乘法

GMOJ6282 向量

使用 192/256 位整数对无符号 64 位整数向量的点积求和的最快方法?

向量乘积的几何意义

为什么两个numpy (n,)向量的矩阵@乘积是点积,而不是外积?

Python 中的多处理:Numpy + 向量求和 -> 大幅减速