'Adding a vector to matrix rows in numpy

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.



Solution 1:[1]

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.

Solution 2:[2]

Numpy broadcasting will automatically add a compatible size vector (1D array) to a matrix (2D array, not numpy matrix). It does this by matching shapes based on dimension from right to left, "stretching" missing or value 1 dimensions to match the other. This is explained in https://numpy.org/doc/stable/user/basics.broadcasting.html:

mat:               5 x 3
vec:                   3
vec (broadcasted): 5 x 3

By default, numpy arrays are row-major ("C order"), with axis 0 is "matrix row" and axis 1 is "matrix col", so the broadcasting clones the vector as matrix rows along axis 0.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2