Nico Schlömer
Nico Schlömer

Reputation: 58951

multiply every element in numpy.array a with every element in numpy.array b

Given two numpy.arrays 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.

Additionally, let b have l dimensions.

Upvotes: 6

Views: 3076

Answers (5)

user2357112
user2357112

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

enter image description here

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

Paul Panzer
Paul Panzer

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

Ohjeah
Ohjeah

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

karakfa
karakfa

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

Divakar
Divakar

Reputation: 221764

One approach would be using np.outer and then reshape -

np.outer(a,b).reshape((a.shape + b.shape))

Upvotes: 2

Related Questions