72

So I have a n x d matrix and an n x 1 vector. I'm trying to write a code to subtract every row in the matrix by the vector.

I currently have a for loop that iterates through and subtracts the i-th row in the matrix by the vector. Is there a way to simply subtract an entire matrix by the vector?

Thanks!

Current code:

for i in xrange( len( X1 ) ): X[i,:] = X1[i,:] - X2 

This is where X1 is the matrix's i-th row and X2 is vector. Can I make it so that I don't need a for loop?

3 Answers 3

94

That works in numpy but only if the trailing axes have the same dimension. Here is an example of successfully subtracting a vector from a matrix:

In [27]: print m; m.shape [[ 0 1 2] [ 3 4 5] [ 6 7 8] [ 9 10 11]] Out[27]: (4, 3) In [28]: print v; v.shape [0 1 2] Out[28]: (3,) In [29]: m - v Out[29]: array([[0, 0, 0], [3, 3, 3], [6, 6, 6], [9, 9, 9]]) 

This worked because the trailing axis of both had the same dimension (3).

In your case, the leading axes had the same dimension. Here is an example, using the same v as above, of how that can be fixed:

In [35]: print m; m.shape [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]] Out[35]: (3, 4) In [36]: (m.transpose() - v).transpose() Out[36]: array([[0, 1, 2, 3], [3, 4, 5, 6], [6, 7, 8, 9]]) 

The rules for broadcasting axes are explained in depth here.

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

3 Comments

m-v.transpose() would not work the same in general.
@MadPhysicist The problem is that a one dimensional array in numpy cannot be transposed, as it will be the same as the output. You have to add a dimension to it to transpose it like in the answer of Nagasaki45 or when creating the np.array with the ndmin=2 argument.
@xuiqzy. Very good point. I'll delete the comment. Transposing usually copies memory. A better way might be m - v[:, None]
21

In addition to @John1024 answer, "transposing" a one-dimensional vector in numpy can be done like this:

In [1]: v = np.arange(3) In [2]: v Out[2]: array([0, 1, 2]) In [3]: v = v[:, np.newaxis] In [4]: v Out[4]: array([[0], [1], [2]]) 

From here, subtracting v from every column of m is trivial using broadcasting:

In [5]: print(m) [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]] In [6]: m - v Out[6]: array([[0, 1, 2, 3], [3, 4, 5, 6], [6, 7, 8, 9]]) 

2 Comments

FYI, m-v[:, None] also works if you forget the np.newaxis thing. I would argue that this option is simpler yet.
@ChristianO'Reilly. np.newaxis is None. They refer to the same object. At that point it's what the author considers to be more legible.
0

If you were just creating the vector that gets subtracted, you can also create it with

column_vector = np.array([0,1,2], ndmin=2).T 

to get a column vector, which is only possible if it has dimension 2 or more.
One dimensional numpy arrays are always rows and cannot be transposed!

Then you can just do

each_column_of_matrix_minus_vector = matrix - column_vector 

to subtract column_vector from every column of matrix.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.