numpy (n, m) 和 (n, k) 到 (n, m, k)

numpy (n, m) and (n, k) to (n, m, k)

xnp.array 形状 (n, m)

ynp.array 形状 (n, k)

计算形状 (n, m, k) 的张量 z 的正确方法是什么

for all i in [0, n - 1]
z[i] = np.dot(x[i][:, np.newaxis], y[i][np.newaxis, :])

?

换句话说,每对行(x_i, y_i)给出一个形状为(m, k)的矩阵。

我查看了 np.tensordot,但经过多次试验后,我找不到其 axes 参数的正确值。我不确定它是否适合这项工作。

一个简单的 np.matmul(x[:, :, None], y[:, None, :]) 就成功了。

来自 numpy.matmul 的文档:

If either argument is N-D, N > 2, it is treated as a stack of matrices residing in the last two indexes and broadcast accordingly.

这正是我想要做的。

您可以这样使用 np.einsum()

z = np.einsum('ij,ik->ijk', x, y)

从快速测试来看,这也比基于 np.matmul() 的方法更快(除了非常小的输入):

import numpy as np


x = np.random.randint(1, 100, (2, 3))
y = np.random.randint(1, 100, (2, 4))

%timeit np.einsum('ij,ik->ijk', x, y)
# 100000 loops, best of 3: 3.14 µs per loop
%timeit np.matmul(x[:, :, None], y[:, None, :])
# 100000 loops, best of 3: 2,07 µs per loop


x = np.random.randint(1, 100, (20, 30))
y = np.random.randint(1, 100, (20, 40))

%timeit np.einsum('ij,ik->ijk', x, y)
# 10000 loops, best of 3: 32.1 µs per loop
%timeit np.matmul(x[:, :, None], y[:, None, :])
# 10000 loops, best of 3: 76.8 µs per loop


x = np.random.randint(1, 100, (200, 300))
y = np.random.randint(1, 100, (200, 400))

%timeit np.einsum('ij,ik->ijk', x, y)
# 10 loops, best of 3: 48.7 ms per loop
%timeit np.matmul(x[:, :, None], y[:, None, :])
# 10 loops, best of 3: 68.2 ms per loop

np.dot() 对广播视图的应用如下:

np.dot(x[:, :, None], y[:, None, :])

不会起作用(它甚至不会达到正确的形状)。

(已编辑)