4

I have a numpy array like:

import numpy as np
a = np.array([[1,0,1,0],
             [1,1,0,0],
             [1,0,1,0],
             [0,0,1,1]])

I would like to calculate euclidian distance between each pair of rows.

from scipy.spatial import distance
for i in range(0,a.shape[0]):
    d = [np.sqrt(np.sum((a[i]-a[j])**2)) for j in range(i+1,a.shape[0])]
    print(d)

[1.4142135623730951, 0.0, 1.4142135623730951]

[1.4142135623730951, 2.0]

[1.4142135623730951]

[]

Is there any better pythonic way to do this since i have to run this code on a huge numpy array?

5
  • Do the points have arbitrary dimensions, or is it always 4d? Commented Apr 12, 2017 at 10:29
  • Did you look at : distance.pdist? That should solve it with : distance.pdist(a). What's should be the final output like? Commented Apr 12, 2017 at 10:30
  • @Divakar among euclidean distance between all pair of row vectors I want the k farthest vectors. Commented Apr 12, 2017 at 10:44
  • @divakar Sir, that worked Commented Apr 12, 2017 at 11:03
  • Also, have a look at at KDTree - docs.scipy.org/doc/scipy-0.14.0/reference/generated/… Commented Apr 12, 2017 at 11:20

3 Answers 3

15

In terms of something more "elegant" you could always use scikitlearn pairwise euclidean distance:

from sklearn.metrics.pairwise import euclidean_distances
euclidean_distances(a,a)

having the same output as a single array.

array([[ 0.        ,  1.41421356,  0.        ,  1.41421356],
       [ 1.41421356,  0.        ,  1.41421356,  2.        ],
       [ 0.        ,  1.41421356,  0.        ,  1.41421356],
       [ 1.41421356,  2.        ,  1.41421356,  0.        ]])
Sign up to request clarification or add additional context in comments.

3 Comments

I think it is giving me the euclidean distance between each pair of points but I want it between each pair of rows. Consider one row represents one 1d vector.
I am sorry i forgot to mention it in my question that one row is one 1d vector.
That worked. Thank you. I got it wrong. Each entry is the distance between ith and jth row of an mXn array where i< j<m.
12

And for completeness, einsum is often referenced for distance calculations.

a = np.array([[1,0,1,0],
         [1,1,0,0],
         [1,0,1,0],
         [0,0,1,1]])

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

np.sqrt(np.einsum('ijk, ijk->ij', a-b, a-b))

array([[ 0.        ,  1.41421356,  0.        ,  1.41421356],
       [ 1.41421356,  0.        ,  1.41421356,  2.        ],
       [ 0.        ,  1.41421356,  0.        ,  1.41421356],
       [ 1.41421356,  2.        ,  1.41421356,  0.        ]])

Comments

0

I used itertools.combinations together with np.linalg.norm of the difference vector (this is the euclidean distance):

import numpy as np
import itertools
a = np.array([[1,0,1,0],
              [1,1,0,0],
              [1,0,1,0],
              [0,0,1,1]])

print([np.linalg.norm(x[0]-x[1]) for x in itertools.combinations(a, 2)])

For understanding have a look at this example from the docs:
combinations('ABCD', 2) gives AB AC AD BC BD CD. In your case, A, B, C and D are the rows of your matrix a, so the term x[0]-x[1] appearing in the above code is the difference vector of the vectors in the rows of a.

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.