0

I'm hoping to calculate the distances between two points in a (Nx1) numpy array, i.e.:

a = [2, 5, 5, 12, 5, 3, 10, 8, 1, 3, 1]

I'm hoping to get a square matrix with the (normed) distances between each point:

sq = [[0, |2-5|, |2-5|, |2-12|, |2-5|, ...],
        [|5-2|, 0, ...], ...]

So far, what I have doesn't work, giving wrong values for the square distance matrix. Is there a way to (I'm not sure if it is the correct term?) vectorise my method too, but am unfamiliar with the advanced indexing.

What I currently have is the following:

sq = np.zero((len(a), len(a))

for i in a:
    for j in len(a+1):
        sq[i,j] = np.abs(a[:,0] - a[:,0])

Would appreciate any help!

Joker
  • 81
  • 5
  • Does this answer your question? [Populate numpy matrix from the difference of two vectors](https://stackoverflow.com/questions/9704565/populate-numpy-matrix-from-the-difference-of-two-vectors) – Nils Werner Dec 15 '19 at 23:06

3 Answers3

0

With numpy the following line might be the shortest to your result:

import numpy as np
a = np.array([2, 5, 5, 12, 5, 3, 10, 8, 1, 3, 1])
sq = np.array([np.array([(np.abs(i - j)) for j in a]) for i in a])
print(sq)

The following would give you the desired result without numpy.

a = [2, 5, 5, 12, 5, 3, 10, 8, 1, 3, 1]
sq = []
for i in a:
    distances = []
    for j in a:
        distances.append(abs(i-j))
    sq.append(distances)
print(sq)

With both, the result comes as:

[[0, 3, 3, 10, 3, 1, 8, 6, 1, 1, 1], [3, 0, 0, 7, 0, 2, 5, 3, 4, 2, 4], [3, 0, 0, 7, 0, 2, 5, 3, 4, 2, 4], [10, 7, 7, 0, 7, 9, 2, 4, 11, 9, 11], [3, 0, 0, 7, 0, 2, 5, 3, 4, 2, 4], [1, 2, 2, 9, 2, 0, 7, 5, 2, 0, 2], [8, 5, 5, 2, 5, 7, 0, 2, 9, 7, 9], [6, 3, 3, 4, 3, 5, 2, 0, 7, 5, 7], [1, 4, 4, 11, 4, 2, 9, 7, 0, 2, 0], [1, 2, 2, 9, 2, 0, 7, 5, 2, 0, 2], [1, 4, 4, 11, 4, 2, 9, 7, 0, 2, 0]]

miwin
  • 1,160
  • 10
  • 12
0

There may be more than one way to do this but one way is to only use numpy operations instead of loops because internally python does lots of optimizations for numpy arrays.

One way to do only using array operations is to create an NxN matrix by repeating the original matrix (a) N times. This will create a matrix N times.

E.g:

a = [1, 2, 3]

b = [[1 , 2, 3], [1 , 2, 3], [1 , 2, 3]]

Then you can do a matrix, array operation of

ans = abs(b - a) 

Assuming a is numpy array, you can do:

b = np.repeat(a,a.shape).reshape((a.shape[0],a.shape[0]))

ans = np.abs(b - a)
FBruzzesi
  • 6,385
  • 3
  • 15
  • 37
HereToLearn
  • 41
  • 1
  • 5
0

I think that by exploiting numpy broadcasting, this is the faster solution:

a = [2, 5, 5, 12, 5, 3, 10, 8, 1, 3, 1]
a = np.array(a).reshape(-1,1)
sq = np.abs(a.T-a) 

sq 
array([[ 0,  3,  3, 10,  3,  1,  8,  6,  1,  1,  1],
       [ 3,  0,  0,  7,  0,  2,  5,  3,  4,  2,  4],
       [ 3,  0,  0,  7,  0,  2,  5,  3,  4,  2,  4],
       [10,  7,  7,  0,  7,  9,  2,  4, 11,  9, 11],
       [ 3,  0,  0,  7,  0,  2,  5,  3,  4,  2,  4],
       [ 1,  2,  2,  9,  2,  0,  7,  5,  2,  0,  2],
       [ 8,  5,  5,  2,  5,  7,  0,  2,  9,  7,  9],
       [ 6,  3,  3,  4,  3,  5,  2,  0,  7,  5,  7],
       [ 1,  4,  4, 11,  4,  2,  9,  7,  0,  2,  0],
       [ 1,  2,  2,  9,  2,  0,  7,  5,  2,  0,  2],
       [ 1,  4,  4, 11,  4,  2,  9,  7,  0,  2,  0]])
FBruzzesi
  • 6,385
  • 3
  • 15
  • 37