23
votes

Is there a fast way in numpy to add a vector to every row or column of a matrix.

Lately, I have been tiling the vector to the size of the matrix, which can use a lot of memory. For example

    mat=np.arange(15)
    mat.shape=(5,3)

    vec=np.ones(3)
    mat+=np.tile(vec, (5,1))

The other way I can think of is using a python loop, but loops are slow:

    for i in xrange(len(mat)):
        mat[i,:]+=vec

Is there a fast way to do this in numpy without resorting to C extensions?

It would be nice to be able to virtually tile a vector, like a more flexible version of broadcasting. Or to be able to iterate an operation row-wise or column-wise, which you may almost be able to do with some of the ufunc methods.

1
Could you give another example? The one you've given would give the same answer just with mat + vec, so I'm not sure exactly what you're after. [Incidentally, this is an array, not a matrix.]DSM
by matrix, I mean a 2-d array (a matrix in the mathematical sense)user1149913
I want to add the same 1-d array to every row of the 2d arrayuser1149913
In numpy, a matrix is different from a 2d array. For example, multiplication is matrix multiplication on matrix objects but elementwise on array objects, so it's a good idea to keep them distinct.DSM

1 Answers

35
votes

For adding a 1d array to every row, broadcasting already takes care of things for you:

mat += vec

However more generally you can use np.newaxis to coerce the array into a broadcastable form. For example:

mat + np.ones(3)[np.newaxis,:]

While not necessary for adding the array to every row, this is necessary to do the same for column-wise addition:

mat + np.ones(5)[:,np.newaxis]

EDIT: as Sebastian mentions, for row addition, mat + vec already handles the broadcasting correctly. It is also faster than using np.newaxis. I've edited my original answer to make this clear.