如何使用我的numpy数组(3000,3)和(3,2,3000)进行广播

问题描述 投票:3回答:2

我有2个阵列,目前形状为v1 =(3000,3),v2 =(3,2,3000)。 3000是时间维度,因此v1具有3000(1,3)个样本,v2具有3000(3,2)个样本。我希望沿着3000维进行矩阵乘法和广播,以便得到3000(1,2)个向量作为回报。

我尝试过重塑,以便v1 =(1,3,3000)和v2 =(3,2,300),这会产生一个错误,表示形状没有对齐。

码:

v1 = np.ones((1,3,3000)) +1
v2 = np.ones((3,2,3000)) - 0.5
np.dot(v1,v2)
python numpy matrix-multiplication tensor broadcasting
2个回答
4
投票

随着qazxsw poi的形状qazxsw poi和qazxsw poi作为qazxsw poi,我们可以使用v1 -

(3000,3)

这给了我们一个形状v2的输出。

我们可以在(3,2,3000)np.einsum arg。使用np.einsum('ij,jki->ik',v1,v2) ,它在内部利用(3000,2),并使用optimize度假村进行简单的C循环。那种np.einsum方式也需要一些设置工作。因此,如果轴的长度适当减少,我们可能希望将该标志设置为optimize = TrueBLAS。在这种情况下,似乎那些轴确实很短,所以我们可能更好地使用默认值:optimize = False输入。


3
投票

我建议你不要使用BLAS旗,因为它有效率,出于一些奇怪的原因。此外,我建议您明确地将2D数组推广到3D,执行批处理矩阵乘法,然后挤压结果数组的单例维度,如果最后需要2D数组作为最终结果。请找到以下代码:

True

因此,正如我们从上面的时间中看到的那样,我们获得了大约。通过不使用False标志2倍加速。此外,明确地将数组整形为3D可以更好地理解当我们使用optimize = False时发生的事情。

注意:时间是使用最新的NumPy版本optimize=True进行的


附:了解更多关于# sample arrays In [25]: v1 = np.random.random_sample((3000, 3)) In [26]: v2 = np.random.random_sample((3, 2, 3000)) # Divakar's approach In [27]: %timeit np.einsum('ij,jki->ik',v1,v2, optimize=True) 80.7 µs ± 792 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each) # needed for future use In [28]: res_optimized = np.einsum('ij,jki->ik',v1,v2, optimize=True) # promoting to 3D array and swapping axes In [29]: v1 = v1[:, np.newaxis, :] In [30]: v2 = np.moveaxis(v2, 2, 0) # perform batch matrix multiplication In [31]: %timeit np.einsum("bij, bjk -> bik", v1, v2) 47.9 µs ± 496 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each) # for sanity checking In [32]: res = np.einsum("bij, bjk -> bik", v1, v2) In [33]: res.shape, res_optimized.shape Out[33]: ((3000, 1, 2), (3000, 2)) # squeeze the singleton dimension and perform sanity check with Divakar's approach In [34]: np.allclose(res.squeeze(), res_optimized) Out[34]: True 的信息

© www.soinside.com 2019 - 2024. All rights reserved.