如何使用我的numpy阵列(3000,3)和(3,23000)进行广播

2024-04-20 07:31:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前有两个数组,形状为v1=(3000,3)和v2=(3,23000)。3000是一个时间维度,因此v1有3000(1,3)个样本,v2有3000(3,2)个样本。我希望做矩阵乘法和广播沿3000维,这样我得到3000(1,2)向量作为回报。你知道吗

我尝试过重塑,使v1=(1,33000)和v2=(3,2300),这会给出一个错误,表示形状没有对齐。你知道吗

代码:

v1 = np.ones((1,3,3000)) +1
v2 = np.ones((3,2,3000)) - 0.5
np.dot(v1,v2)

Tags: 代码错误np时间ones矩阵数组向量
2条回答

我建议您不要使用optimize=True标志,因为它是高效的,出于一些奇怪的原因。另外,如果最终需要一个2D数组作为最终结果,我建议您显式地将2D数组提升到3D,执行批处理矩阵乘法,然后压缩结果数组的单例维数。请查找以下代码:

# 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

因此,从上面的计时可以看出,不使用optimize=True标志可以获得大约2倍的加速比。另外,显式地将数组整形为3D可以更好地理解使用numpy.einsum()时发生的事情。你知道吗

注意:计时是使用最新的NumPy版本'1.16.1'


请阅读更多关于Understanding NumPy einsum()

由于v1的形状(3000,3)v2的形状(3,2,3000),我们可以使用^{}-

np.einsum('ij,jki->ik',v1,v2)

这给了我们一个shape(3000,2)的输出。你知道吗

我们可以在np.einsum中使用optimizearg。使用optimize = True,它在内部利用BLAS,使用optimize = False求助于简单的C循环。这种BLAS方式也需要一些设置工作。因此,对于经过求和缩减的轴的适当长度,我们可能希望将该标志设置为TrueFalse。在本例中,这些轴似乎很短,因此我们最好使用默认的:optimize = False输入。你知道吗

相关问题 更多 >