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

The outer method of NumPy ufuncs treats multidimensional input the way you want, so you could do

numpy.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
import perfplot


def multiply_outer(data):
    a, b = data
    return numpy.multiply.outer(a, b)


def outer_reshape(data):
    a, b = data
    return numpy.outer(a, b).reshape((a.shape + b.shape))


def tensor_dot(data):
    a, b = data
    return numpy.tensordot(a, b, 0)


perfplot.save(
    "out.png",
    setup=lambda n: (numpy.random.rand(n, n), numpy.random.rand(n, n)),
    kernels=[multiply_outer, outer_reshape, tensor_dot],
    n_range=[2 ** k for k in range(7)],
    logx=True,
    logy=True,
)

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

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

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