给出两个矩阵
A: m * r
B: n * r
我想生成另一个矩阵C: m * n
,每个条目C_ij
都是由A_i
和B_j
的外积计算的矩阵。
例如,
A: [[1, 2],
[3, 4]]
B: [[3, 1],
[1, 2]]
给出
C: [[[3, 1], [[1 ,2],
[6, 2]], [2 ,4]],
[9, 3], [[3, 6],
[12,4]], [4, 8]]]
我可以使用for循环来完成,比如
for i in range (A.shape(0)):
for j in range (B.shape(0)):
C_ij = np.outer(A_i, B_j)
我想知道是否有一种矢量化的方法来进行此计算以加快速度?
答案 0 :(得分:13)
爱因斯坦符号很好地表达了这个问题
In [85]: np.einsum('ac,bd->abcd',A,B)
Out[85]:
array([[[[ 3, 1],
[ 6, 2]],
[[ 1, 2],
[ 2, 4]]],
[[[ 9, 3],
[12, 4]],
[[ 3, 6],
[ 4, 8]]]])
答案 1 :(得分:6)
temp = numpy.multiply.outer(A, B)
C = numpy.swapaxes(temp, 1, 2)
NumPy ufuncs,例如multiply
,有一个outer
方法几乎可以满足您的需求。以下内容:
temp = numpy.multiply.outer(A, B)
生成temp[a, b, c, d] == A[a, b] * B[c, d]
的结果。你想要C[a, b, c, d] == A[a, c] * B[b, d]
。 swapaxes
调用会重新排列temp
,使其按您想要的顺序排列。
答案 2 :(得分:0)
使用numpy;
In [1]: import numpy as np
In [2]: A = np.array([[1, 2], [3, 4]])
In [3]: B = np.array([[3, 1], [1, 2]])
In [4]: C = np.outer(A, B)
In [5]: C
Out[5]:
array([[ 3, 1, 1, 2],
[ 6, 2, 2, 4],
[ 9, 3, 3, 6],
[12, 4, 4, 8]])
获得所需结果后,您可以使用numpy.reshape()
将其塑造成几乎任何您想要的形状;
In [6]: C.reshape([4,2,2])
Out[6]:
array([[[ 3, 1],
[ 1, 2]],
[[ 6, 2],
[ 2, 4]],
[[ 9, 3],
[ 3, 6]],
[[12, 4],
[ 4, 8]]])
答案 3 :(得分:0)
既然要使用C_ij = A_i * B_j
,只需在列向量A和行向量B的元素乘积上进行numpy广播即可实现,如下所示:
# import numpy as np
# A = [[1, 2], [3, 4]]
# B = [[3, 1], [1, 2]]
A, B = np.array(A), np.array(B)
C = A.reshape(-1,1) * B.reshape(1,-1)
# same as:
# C = np.einsum('i,j->ij', A.flatten(), B.flatten())
print(C)
输出:
array([[ 3, 1, 1, 2],
[ 6, 2, 2, 4],
[ 9, 3, 3, 6],
[12, 4, 4, 8]])
然后可以通过使用numpy.dsplit()
或numpy.array_split()
如下获得所需的四个子矩阵:
np.dsplit(C.reshape(2, 2, 4), 2)
# same as:
# np.array_split(C.reshape(2,2,4), 2, axis=2)
输出:
[array([[[ 3, 1],
[ 6, 2]],
[[ 9, 3],
[12, 4]]]),
array([[[1, 2],
[2, 4]],
[[3, 6],
[4, 8]]])]