给定两个 numpy.array
数组 a
和 b
,
c = numpy.outer(a, b)
返回一个二维数组,其中c[i, j] == a[i] * b[j]
。现在,想象一下a
具有k
个维度。
- 哪个操作返回一个维度为
k+1
的数组c
,其中c[..., j] == a * b[j]
?
另外,让b
具有l
个维度。
- 哪个操作返回一个维度为
k+1
的数组c
,其中c[..., i1, i2, i3] == a * b[i1, i2, i3]
?
NumPy的ufunc的outer
方法可以按你想要的方式处理多维输入,所以你可以这样做:
np.multiply.outer(a, b)
使用 numpy.outer
不如其他方法快。
这里提出的所有解决方案速度都相同;对于小数组,multiply.outer
稍微占优势。
生成该图像的代码:
import numpy as np
import perfplot
def multiply_outer(a, b):
return np.multiply.outer(a, b)
def outer_reshape(a, b):
return np.outer(a, b).reshape((a.shape + b.shape))
def tensor_dot(a, b):
return np.tensordot(a, b, 0)
b = perfplot.bench(
setup=lambda n: (np.random.rand(n, n), np.random.rand(n, n)),
kernels=[multiply_outer, outer_reshape, tensor_dot],
n_range=[2 ** k for k in range(7)],
)
b.save("out.png")
一种方法是使用np.outer
,然后再使用reshape
-
np.outer(a,b).reshape((a.shape + b.shape))
我认为np.tensordot
也可以使用。
c = np.tensordot(a, b, 0)
inds = np.reshape(np.indices(b.shape), (b.ndim, -1))
for ind in inds.T:
ind = tuple(ind)
assert np.allclose(a * b[ind], c[(...,) + ind])
else:
print('no error')
# no error
np.einsum是你要寻找的。
c[..., j] == a * b[j]
应该是
c = np.einsum('...i,j -> ...ij', a, b)
而c[..., i1, i2, i3] == a * b[i1, i2, i3]
应该是
c = np.einsum('i,...jkl -> ...ijkl', a, b)
> np.kron(np.eye(2), np.ones((2,2)))
array([[ 1., 1., 0., 0.],
[ 1., 1., 0., 0.],
[ 0., 0., 1., 1.],
[ 0., 0., 1., 1.]])