Stefan Falk
Stefan Falk

Reputation: 25387

How to apply a function to all vector pairs in a matrix

I want to calculate the sum of distances of a row vector with respect to all other row vectors in a matrix. Thus the result has to be a square matrix.

For a matrix M:

    | a b c |   | v1 |
M = |       | = |    |
    | c d e |   | v2 |

I'd like to calculate:

    | (a-a)+(b-b)+(c-c)  (a-c)+(b-d)+(c-e) |   | v1-v1  v1-v2 |
M = |                                      | = |              |
    | (c-a)+(d-b)+(e-c)  (c-c)+(d-d)+(e-e) |   | v2-v1  v2-v2 |

I am aware that I could do this in a nested for loop but is there a more elegant way to apply this, or any other operation like this, to a matrix with numpy?

Upvotes: 2

Views: 231

Answers (1)

Divakar
Divakar

Reputation: 221524

Use broadcasting -

(M[:,None,:]- M).sum(2)

Sample run -

In [41]: M
Out[41]: 
array([[8, 3, 2],
       [6, 1, 2]])

In [42]: (M[:,None,:]- M).sum(2)
Out[42]: 
array([[ 0,  4],
       [-4,  0]])

If M is a NumPy matrix, get an array view into it with np.asarray() and then use it, like so -

M_arr = np.asarray(M)
out = np.asmatrix((M_arr[:,None,:]- M_arr).sum(2))

Sample run -

In [69]: M = np.asmatrix(np.random.randint(0,9,(2,3)))

In [70]: M
Out[70]: 
matrix([[3, 8, 8],
        [0, 5, 0]])

In [71]: M_arr = np.asarray(M)

In [72]: np.asmatrix((M_arr[:,None,:]- M_arr).sum(2))
Out[72]: 
matrix([[  0,  14],
        [-14,   0]])

Let's also verify that are we indeed working with a view there with np.asarray() -

In [73]: np.may_share_memory(M, M_arr)
Out[73]: True

Upvotes: 3

Related Questions