25

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.

4
  • 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.] Commented Aug 15, 2012 at 14:31
  • by matrix, I mean a 2-d array (a matrix in the mathematical sense) Commented Aug 15, 2012 at 14:39
  • I want to add the same 1-d array to every row of the 2d array Commented Aug 15, 2012 at 14:40
  • 1
    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. Commented Aug 15, 2012 at 14:48

2 Answers 2

41

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.

Sign up to request clarification or add additional context in comments.

8 Comments

Here its not even necessary, but if mat would be shaped (3,5) then using np.ones(3)[:,np.newaxis] does the trick.
@Sebastian: You are right; I was just trying to show a general method of getting the broadcasting correct since the OP asked for both columns and row addition.
Okay, I must be really stupid today. Could someone explain to me why this isn't just a slower version of mat + vec?
@DSM not being stupid. See my edit above. I should have been clear that what I was demonstrating was a general method for coercing arrays into a broadcasting friendly shape.
@Trevor The error is telling you that you are trying to add two numpy arrays with different datatypes, which is causing the error. Making both mat and vec with the same dtype.
|
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.