4

I have a one dimensional array, lets say:

import numpy as np
inp_vec = np.array([1, 2, 3])

Now, I would like to construct a matrix of the form

[[1 - 1, 1 - 2, 1 - 3],
 [2 - 1, 2 - 2, 2 - 3],
 [3 - 1, 3 - 2, 3 - 3]])

Of course it can be done with for loops but is there a more elegant way to do this?

ddejohn
  • 8,775
  • 3
  • 17
  • 30
user3176500
  • 389
  • 2
  • 6
  • 15

5 Answers5

6

This I find a nice way as well:

np.subtract.outer([1,2,3], [1,2,3])
4

This seems to work:

In [1]: %paste
import numpy as np
inp_vec = np.array([1, 2, 3])

## -- End pasted text --

In [2]: inp_vec.reshape(-1, 1) - inp_vec
Out[2]: 
array([[ 0, -1, -2],
       [ 1,  0, -1],
       [ 2,  1,  0]])

Explanation:

You first reshape the array to nx1. When you subtract a 1D array, they are both broadcast to nxn:

array([[ 1,  1,  1],
       [ 2,  2,  2],
       [ 3,  3,  3]])

and

array([[ 1,  2,  3],
       [ 1,  2,  3],
       [ 1,  2,  3]])

Then the subtraction is done element-wise, which yields the desired result.

Lev Levitsky
  • 63,701
  • 20
  • 147
  • 175
  • Hi, thanks for the answer and the explanation, however can you point me to some reference explaining the expansion from nx1 to nxn. It's a bit mysterious. Also how do I know that the subtraction is made columnwise. Thanks – user3176500 Sep 26 '14 at 08:31
  • @user3176500 I guess it's not really correct to say that the subtraction is made column-wise or row-wise, see the edit. For a short explanation of the rules, check [this tutorial](http://wiki.scipy.org/Tentative_NumPy_Tutorial#head-c533fb9a3f1aa90d96e4d8329c1c2f975474c8bf). – Lev Levitsky Sep 26 '14 at 08:39
  • sorry, missed the "they are both broadcast to nxn". Of course the subtraction is made element-wise. Thanks again – user3176500 Sep 26 '14 at 08:43
  • @user3176500 You didn't miss it, I edited the answer in response tou your comment :) Glad to have helped. – Lev Levitsky Sep 26 '14 at 09:12
3
import numpy as np
inp_vec = np.array([1, 2, 3])

a, b = np.meshgrid(inp_vec, inp_vec)
print(b - a)

Output:

Array([[ 0 -1 -2],
       [ 1  0 -1],
       [ 2  1  0]])
1

Using np.nexaxis

import numpy as np
inp_vec = np.array([1, 2, 3])

output = inp_vec[:, np.newaxis] - inp_vec

Output

array([[ 0, -1, -2],
       [ 1,  0, -1],
       [ 2,  1,  0]])
Peter R
  • 11
  • 1
1

This is a quick and simple alternative.

import numpy as np
inp_vec = np.array([1, 2, 3])

N = len(inp_vec)
np.reshape(inp_vec,(N,1)) - np.reshape(inp_vec,(1,N))

Madlad
  • 125
  • 12