如果我有两个形状为(N, 3)
的numpy数组
array1 = np.array([[x1, y1, 1],
........
[xn, yn, 1]])
array2 = np.array([[u1, v1, 1],
........
[un, vn, 1]])
我想要
A = np.array([[x1 * u1, x1 * v1, x1, y1 * u1, y1 * v1, y1, u1, v1, 1],
.........
[xn * un, xn * vn, xn, yn * un, yn * vn, yn, un, vn, 1]]
在不使用for
循环迭代的情况下,我该如何做到这一点?
您显然希望沿第二维广播乘法。解决这类问题的诀窍是记住,numpy默认情况下是按照C的顺序移动/重塑的。
让我们分析输出的行,看看如何排列乘积。你有
[x1 * u1, x1 * v1, x1 * 1, y1 * u1, y1 * v1, y1 * 1, u1, v1, 1]
这是
的修改版本[[x1 * u1, x1 * v1, x1 * 1],
[y1 * u1, y1 * v1, y1 * 1],
[ 1 * u1, 1 * v1, 1 * 1]]
依次是乘积
array1[0][:, None] * array2[0][None, :]
因此,您想要的产品保留第一个维度,并广播第二个维度,如上所示。然后将最后两个维度折叠在一起,得到部分克罗内克积:
A = (array1[:, :, None] * array2[:, None, :]).reshape(array1.shape[0], -1)
这就是Kronecker产品。您可以使用np.kron()
函数这样做:
import numpy as np
array1 = np.array([[1,2,1],
[3,4,1]])
array2 = np.array([[3,4,1],
[1,0,1]])
N = array1.shape[0]
result = np.kron(array1, array2)
# A (NxN) x 9 output
#array([[ 3, 4, 1, 6, 8, 2, 3, 4, 1],
# [ 1, 0, 1, 2, 0, 2, 1, 0, 1],
# [ 9, 12, 3, 12, 16, 4, 3, 4, 1],
# [ 3, 0, 3, 4, 0, 4, 1, 0, 1]])
如果你想要一个一对一的克罗内克产品,你也可以使用:
# N x 9
np.kron(array1, array2)[0:N*N:N, :]
#array([[ 3, 4, 1, 6, 8, 2, 3, 4, 1],
# [ 9, 12, 3, 12, 16, 4, 3, 4, 1]])
如果性能很重要,不建议使用。