我试图在三个numpy数组之间采用点积。但是,我正在努力绕过这个问题。
我分别有两个(4)形状的numpy数组a
和b
,以及一个形状为(4,4,3),c
的numpy数组。
import numpy as np
a = np.array([0, 1, 2, 3])
b = np.array([[[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1]],
[[2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2]],
[[3, 3, 3], [3, 3, 3], [3, 3, 3], [3, 3, 3]],
[[4, 4, 4], [4, 4, 4], [4, 4, 4], [4, 4, 4]]])
c = np.array([4, 5, 6, 7])
我想以这样的方式计算点积,即我的结果是3元组。也就是说,首先使用a
点b
,然后点击c
,根据需要进行转置。换句话说,我想计算a
,b
和c
之间的点积,就像c
的形状(4, 4)
一样,但我想要一个3 -tuple结果。
重塑a
和c
,然后计算点积:
a = np.reshape(a, (4, 1))
c = np.reshape(c, (4, 1))
tmp = np.dot(a.T, b) # now has shape (1, 4, 3)
result = np.dot(tmp, c)
理想情况下,我现在应该:
print(result.shape)
>> (1, 1, 3)
但我收到了错误
ValueError:形状(1,4,3)和(4,1)未对齐:3(暗淡2)!= 4(暗淡0)
我也试过使用numpy的tensordot函数,但没有运气。
答案 0 :(得分:1)
基本Properties
规则是:A的最后一个轴,B的第二个到最后一个
dot(A,B)
In [965]: a.shape
Out[965]: (4,)
In [966]: b.shape
Out[966]: (4, 4, 3)
(和a
)是1d。它的(4,)可以与c
的第2(4)点对齐:
b
在输出中使用In [967]: np.dot(a,b).shape
Out[967]: (4, 3)
会产生一个(3,)数组
c
使用等效的In [968]: np.dot(c, np.dot(a,b))
Out[968]: array([360, 360, 360])
:
einsum
但是如果我们希望In [971]: np.einsum('i,jik,j->k',a,b,c)
Out[971]: array([360, 360, 360])
在a
的第一轴上行动呢?使用b
这很容易做到:
einsum
要对In [972]: np.einsum('i,ijk,j->k',a,b,c)
Out[972]: array([440, 440, 440])
执行相同操作,我们只需切换dot
和a
:
c
或转置In [973]: np.dot(a, np.dot(c,b))
Out[973]: array([440, 440, 440])
的轴:
b
如果In [974]: np.dot(c, np.dot(a,b.transpose(1,0,2)))
Out[974]: array([440, 440, 440])
和a
有不同的长度,这个换位问题会更清晰。例如A(2,)和(4,),(2,4,3)或(4,2,3)。
在
c
你有一个(1,4a)点缀着(4,4a,3)。结果是(1,4,3)。我添加了tmp = np.dot(a.T, b) # now has shape (1, 4, 3)
以确定何时组合轴。
要应用(4,1)a
,我们必须进行相同的转置:
c
没有转置, In [977]: np.dot(c[:,None].T, np.dot(a[:,None].T, b))
Out[977]: array([[[360, 360, 360]]])
In [978]: _.shape
Out[978]: (1, 1, 3)
会做同样的事情。
我希望numpy会在最后一个轴上自动分配。也就是说,如果有意义的话,点积将在两个第一轴上运行。
鉴于我在开始时引用的np.dot(c[None,:], np.dot(a[None,:], b))
规则,这没有意义。但是如果我们转换dot
所以(3)轴是第一个,它可以“携带”,使用最后一个,第二个到最后一个。
b
答案 1 :(得分:0)
不是自动化但是完成工作:
np.einsum('i,ijk,j->k',a,b,c)
# array([440, 440, 440])
这会计算形状(3,)的d
,使d_k = sum_{ij} a_i b_{ijk} c_j
。
答案 2 :(得分:0)
您将(1,4,3)矩阵乘以(4,1)矩阵,因此不可能,因为b中有3页(1,4)矩阵。如果你想用矩阵b的每一页乘以c,只需将每一页分别相乘。
a = np.array([0, 1, 2, 3])
b = np.array([[[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1]],
[[2, 2, 2], [2, 2, 2], [2, 2, 2], [2, 2, 2]],
[[3, 3, 3], [3, 3, 3], [3, 3, 3], [3, 3, 3]],
[[4, 4, 4], [4, 4, 4], [4, 4, 4], [4, 4, 4]]])
c = np.array([4, 5, 6, 7])
a = np.reshape(a, (4, 1))
c = np.reshape(c, (4, 1))
tmp = np.dot(a.T, b) # now has shape (1, 4, 3)
result = np.dot(tmp[:,:,0], c)
for i in range(1,3):
result = np.dstack((result, np.dot(tmp[:,:,i], c)))
print np.shape(result)
所以你有大小(1,1,3)的结果