33

I am new to Numpy and I would like to ask you how to calculate euclidean distance between points stored in a vector.

Let's assume that we have a numpy.array each row is a vector and a single numpy.array. I would like to know if it is possible to calculate the euclidean distance between all the points and this single point and store them in one numpy.array.

Here is an interface:

points #2d list of row-vectors
singlePoint #one row-vector

listOfDistances= procedure( points,singlePoint)

Can we have something like this? Or is it possible to have one command to have the single point as a list of other points and at the end we get a matrix of distances?

Thanks

nmichaels
  • 49,466
  • 12
  • 107
  • 135
pacodelumberg
  • 2,214
  • 4
  • 25
  • 32
  • 1
    Although you want to calculate the distance between a point and a set of points, I think scipy.spatial.distance.cdist still works. You have 2 collections, one of which have only 1 element. http://stackoverflow.com/questions/1871536/euclidean-distance-between-points-in-two-different-numpy-arrays-not-within – Jim Raynor Apr 30 '14 at 21:57
  • @JimRaynor +1 Was exactly what I needed :) – ocean800 Nov 13 '17 at 05:33

5 Answers5

33

To get the distance you can use the norm method of the linalg module in numpy:

np.linalg.norm(x - y)
Christian
  • 1,341
  • 1
  • 16
  • 35
  • 1
    This should be the right answer, you can also play with axis parameter (depends on what you want to do) X is you N*2 vector y is your point – Vadim Kirilchuk Apr 14 '18 at 12:00
31

While you can use vectorize, @Karl's approach will be rather slow with numpy arrays.

The easier approach is to just do np.hypot(*(points - single_point).T). (The transpose assumes that points is a Nx2 array, rather than a 2xN. If it's 2xN, you don't need the .T.

However this is a bit unreadable, so you write it out more explictly like this (using some canned example data...):

import numpy as np
single_point = [3, 4]
points = np.arange(20).reshape((10,2))

dist = (points - single_point)**2
dist = np.sum(dist, axis=1)
dist = np.sqrt(dist)
Joe Kington
  • 275,208
  • 71
  • 604
  • 463
  • 7
    Even though this does the job, you'd better use existing functions like np.linalg.norm(x - y, axis=1) or distance.euclidean or cdist. – Vadim Kirilchuk Apr 14 '18 at 12:02
  • 6
    To expand on @VadimKirilchuk's comment in the context of the example above: `np.linalg.norm(points - single_point, axis=1)` – orangepips May 24 '19 at 04:12
7
import numpy as np
def distance(v1, v2):
    return np.sqrt(np.sum((v1 - v2) ** 2))    
Dima
  • 71
  • 1
  • 1
3

To apply a function to each element of a numpy array, try numpy.vectorize.

To do the actual calculation, we need the square root of the sum of squares of differences (whew!) between pairs of coordinates in the two vectors.

We can use zip to pair the coordinates, and sum with a comprehension to sum up the results. That looks like:

sum((x - y) ** 2 for (x, y) in zip(singlePoint, pointFromArray)) ** 0.5
Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
0
import numpy as np
single_point = [3, 4]
points = np.arange(20).reshape((10,2))   
distance = euclid_dist(single_point,points)

def euclid_dist(t1, t2):
    return np.sqrt(((t1-t2)**2).sum(axis = 1))
rombi
  • 199
  • 3
  • 22
  • 5
    While this code snippet may solve the question, [including an explanation](http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – 31piy Jul 23 '18 at 05:46