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

3

假设我有两个矩阵: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个回答

2
这里有一个快速的方法:
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 矩阵每一行元素的乘积。由于 M 是一个矩阵实例,因此结果的形状为 (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 参数以保持二维形状,并使用 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]])

太好了!谢谢。如果我想在乘法之前从向量积中减去某些内容,您有什么建议吗?例如,result = np.empty( (2,4) ) for i in range(2): result[i,:] = np.prod( 1 - np.multiply(np.tile(M[i,:].T , (1,4)), C) , axis=0) - Nolan Conaway

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接