I’m trying to multiply each of the terms in a 2D array by the corresponding terms in a 1D array. This is very easy if I want to multiply every column by the 1D array, as shown in the numpy.multiply function. But I want to do the opposite, multiply each term in the row.
In other words I want to multiply:

``````[1,2,3]   
[4,5,6] * 
[7,8,9]   
``````

and get

``````[0,0,0]
[4,5,6]
[14,16,18]
``````

``````[0,2,6]
[0,5,12]
[0,8,18]
``````

Does anyone know if there’s an elegant way to do that with numpy?
Thanks a lot,
Alex

Normal multiplication like you showed:

``````>>> import numpy as np
>>> m = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> c = np.array([0,1,2])
>>> m * c
array([[ 0,  2,  6],
[ 0,  5, 12],
[ 0,  8, 18]])
``````

If you add an axis, it will multiply the way you want:

``````>>> m * c[:, np.newaxis]
array([[ 0,  0,  0],
[ 4,  5,  6],
[14, 16, 18]])
``````

You could also transpose twice:

``````>>> (m.T * c).T
array([[ 0,  0,  0],
[ 4,  5,  6],
[14, 16, 18]])
``````

I’ve compared the different options for speed and found that – much to my surprise – all options (except `diag`) are equally fast. I personally use

``````A * b[:, None]
``````

(or `(A.T * b).T`) because it’s short. Code to reproduce the plot:

``````import numpy
import perfplot

def newaxis(data):
A, b = data
return A * b[:, numpy.newaxis]

def none(data):
A, b = data
return A * b[:, None]

def double_transpose(data):
A, b = data
return (A.T * b).T

def double_transpose_contiguous(data):
A, b = data
return numpy.ascontiguousarray((A.T * b).T)

def diag_dot(data):
A, b = data
return numpy.dot(numpy.diag(b), A)

def einsum(data):
A, b = data
return numpy.einsum("ij,i->ij", A, b)

perfplot.save(
"p.png",
setup=lambda n: (numpy.random.rand(n, n), numpy.random.rand(n)),
kernels=[
newaxis,
none,
double_transpose,
double_transpose_contiguous,
diag_dot,
einsum,
],
n_range=[2 ** k for k in range(13)],
xlabel="len(A), len(b)",
)
``````

You could also use matrix multiplication (aka dot product):

``````a = [[1,2,3],[4,5,6],[7,8,9]]
b = [0,1,2]
c = numpy.diag(b)

numpy.dot(c,a)
``````

Which is more elegant is probably a matter of taste.

Yet another trick (as of v1.6)

``````A=np.arange(1,10).reshape(3,3)
b=np.arange(3)

np.einsum('ij,i->ij',A,b)
``````

I’m proficient with the numpy broadcasting (`newaxis`), but I’m still finding my way around this new `einsum` tool. So I had play around a bit to find this solution.

Timings (using Ipython timeit):

``````einsum: 4.9 micro
transpose: 8.1 micro
newaxis: 8.35 micro
dot-diag: 10.5 micro
``````

Incidentally, changing a `i` to `j`, `np.einsum('ij,j->ij',A,b)`, produces the matrix that Alex does not want. And `np.einsum('ji,j->ji',A,b)` does, in effect, the double transpose.

For those lost souls on google, using `numpy.expand_dims` then `numpy.repeat` will work, and will also work in higher dimensional cases (i.e. multiplying a shape (10, 12, 3) by a (10, 12)).

``````>>> import numpy
>>> a = numpy.array([[1,2,3],[4,5,6],[7,8,9]])
>>> b = numpy.array([0,1,2])
>>> b0 = numpy.expand_dims(b, axis = 0)
>>> b0 = numpy.repeat(b0, a.shape, axis = 0)
>>> b1 = numpy.expand_dims(b, axis = 1)
>>> b1 = numpy.repeat(b1, a.shape, axis = 1)
>>> a*b0
array([[ 0,  2,  6],
[ 0,  5, 12],
[ 0,  8, 18]])
>>> a*b1
array([[ 0,  0,  0],
[ 4,  5,  6],
[14, 16, 18]])
``````

Why don’t you just do

``````>>> m = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> c = np.array([0,1,2])
>>> (m.T * c).T
``````

??