如何使用广播来加速这段代码?
How to use broadcasting to speed up this code?
我有以下多维数组。第一个轴表示
3 维向量。我想为每个计算 3×3 矩阵 x⋅x'
那些。
我目前的解决方案:
arr.shape
# (3, 64, 64, 33, 187)
dm = arr.reshape(3,-1)
dm.shape
# (3, 25276416)
cov = np.empty((3,3,dm.shape[1]))
cov.shape
# (3, 3, 25276416)
这个 for 循环遍历所有 25,276,416 个元素,大约需要 1 或 2 分钟。
for i in range(dm.shape[1]):
cov[...,i] = dm[:,i].reshape(3,1).dot(dm[:,i].reshape(1,3))
cov = cov.reshape((3,) + arr.shape)
cov.shape
# (3, 3, 64, 64, 33, 187)
好吧,您并没有真正使用 np.dot
通过矩阵乘法来减少任何轴,它只是在那里广播了逐元素乘法。所以,你可以简单地使用 NumPy broadcasting
来完成整个事情,就像这样 -
cov = dm[:,None]*dm
或者直接在 arr
上使用它以避免创建 dm
和所有重塑,就像这样 -
cov = arr[:,None]*arr
我有以下多维数组。第一个轴表示 3 维向量。我想为每个计算 3×3 矩阵 x⋅x' 那些。
我目前的解决方案:
arr.shape
# (3, 64, 64, 33, 187)
dm = arr.reshape(3,-1)
dm.shape
# (3, 25276416)
cov = np.empty((3,3,dm.shape[1]))
cov.shape
# (3, 3, 25276416)
这个 for 循环遍历所有 25,276,416 个元素,大约需要 1 或 2 分钟。
for i in range(dm.shape[1]):
cov[...,i] = dm[:,i].reshape(3,1).dot(dm[:,i].reshape(1,3))
cov = cov.reshape((3,) + arr.shape)
cov.shape
# (3, 3, 64, 64, 33, 187)
好吧,您并没有真正使用 np.dot
通过矩阵乘法来减少任何轴,它只是在那里广播了逐元素乘法。所以,你可以简单地使用 NumPy broadcasting
来完成整个事情,就像这样 -
cov = dm[:,None]*dm
或者直接在 arr
上使用它以避免创建 dm
和所有重塑,就像这样 -
cov = arr[:,None]*arr