Reputation: 58951
Given two numpy.array
s a
and b
,
c = numpy.outer(a, b)
returns an two-dimensional array where c[i, j] == a[i] * b[j]
. Now, imagine a
having k
dimensions.
c
of dimension k+1
where c[..., j] == a * b[j]
?Additionally, let b
have l
dimensions.
c
of dimension k+1
where c[..., i1, i2, i3] == a * b[i1, i2, i3]
?Upvotes: 6
Views: 3076
Reputation: 282168
The outer
method of NumPy ufuncs treats multidimensional input the way you want, so you could do
np.multiply.outer(a, b)
rather than using numpy.outer
.
All solutions suggested here are equally fast; for small arrays, multiply.outer
has a slight edge
Code for generating the image:
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")
Upvotes: 7
Reputation: 53119
I think np.tensordot
also works
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
Upvotes: 2
Reputation: 1307
np.einsum is what you are looking for.
c[..., j] == a * b[j]
should be
c = np.einsum('...i,j -> ...ij', a, b)
and c[..., i1, i2, i3] == a * b[i1, i2, i3]
should be
c = np.einsum('i,...jkl -> ...ijkl', a, b)
Upvotes: 1
Reputation: 67567
I think you're looking for kroneker product
for example
> 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.]])
Upvotes: 1
Reputation: 221764
One approach would be using np.outer
and then reshape
-
np.outer(a,b).reshape((a.shape + b.shape))
Upvotes: 2