numpy tensordot 相关问题
我在使用numpy进行矩阵相乘时遇到了一个具体的问题。这里有一个例子:
P=np.arange(30).reshape((-1,3))
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11],
[12, 13, 14],
[15, 16, 17],
[18, 19, 20],
[21, 22, 23],
[24, 25, 26],
[27, 28, 29]])
我想把每一行和它的转置相乘,这样就能为每一行得到一个3x3的矩阵,比如说对于第一行:
P[0]*P[0][:,np.newaxis]
array([[0, 0, 0],
[0, 1, 2],
[0, 2, 4]])
然后把结果存储在一个三维矩阵M中:
M=np.zeros((10,3,3))
for i in range(10):
M[i] = P[i]*P[i][:,np.newaxis]
我觉得可能有办法不使用循环,或许可以用tensor-dot,但我找不到相关的方法。
有没有人知道该怎么做?
3 个回答
0
这部分解决了问题,使用了 tensordot()
这个函数。
from numpy import arange,tensordot
P = arange(30).reshape((-1,3))
i = 3
T = tensordot(P,P,0)[:,:,i,:]
print T[i]
print tensordot(P[i],P[i],0)
T
里包含了你想要的所有乘积(还有更多),现在只需要把它们提取出来就行了。
1
因为我喜欢使用stride_tricks,所以我会选择这个方法。我相信还有其他的做法。
我们需要改变数组的步幅和形状,把它扩展成三维的。你也可以用P的“转置”版本来做同样的事情,不过在这里我只是重新调整它的形状,然后让广播规则把它拉伸到其他维度。
P=np.arange(30).reshape((-1,3))
astd = numpy.lib.stride_tricks.as_strided
its = P.itemsize
M = astd(P,(10,3,3),(its*3,its,0))*P.reshape((10,1,3))
我想提一下这篇文章,因为它详细解释了stride_tricks.as_strided
的用法。
3
就这么简单:
In []: P= arange(30).reshape(-1, 3)
In []: P[:, :, None]* P[:, None, :]
Out[]:
array([[[ 0, 0, 0],
[ 0, 1, 2],
[ 0, 2, 4]],
[[ 9, 12, 15],
[ 12, 16, 20],
[ 15, 20, 25]],
[[ 36, 42, 48],
[ 42, 49, 56],
[ 48, 56, 64]],
#...
[[729, 756, 783],
[756, 784, 812],
[783, 812, 841]]])
In []: P[1]* P[1][:, None]
Out[]:
array([[ 9, 12, 15],
[12, 16, 20],
[15, 20, 25]])