Distance formula between two points in a list

I realize that there are library constraints on this question, but for completeness if you have N points in an Nx2 numpy ndarray (2D system):

from scipy.spatial.distance import pdist
x = numpy.array([[9.5,7.5],[10.2,19.1],[9.7,10.2]])
mindist = numpy.min(pdist(x))

I always try to encourage people to use numpy/scipy if they are dealing with data that is best stored in a numerical array and it's good to know that the tools are out there for future reference.


Note that the math.sqrt function is both slow and, in this case, unnecessary. Try comparing the distance squared to speed it up (sorting distances vs. distance squared will always produce the same ordering):

def distSquared(p0, p1):
    return (p0[0] - p1[0])**2 + (p0[1] - p1[1])**2

It is more convenient to rewrite your distance() function to take two (x, y) tuples as parameters:

def distance(p0, p1):
    return math.sqrt((p0[0] - p1[0])**2 + (p0[1] - p1[1])**2)

Now you want to iterate over all pairs of points from your list fList. The function iterools.combinations() is handy for this purpose:

min_distance = distance(fList[0], fList[1])
for p0, p1 in itertools.combinations(fList, 2):
    min_distance = min(min_distance, distance(p0, p1))

An alternative is to define distance() to accept the pair of points in a single parameter

def distance(points):
    p0, p1 = points
    return math.sqrt((p0[0] - p1[0])**2 + (p0[1] - p1[1])**2)

and use the key parameter to the built-in min() function:

min_pair = min(itertools.combinations(fList, 2), key=distance)
min_distance = distance(min_pair)

This might work:

oInput = ["9.5 7.5", "10.2 19.1", "9.7 10.2"]

# parse inputs
inp = [(float(j[0]), float(j[1])) for j in [i.split() for i in oInput]]

# initialize results with a really large value
min_distance = float('infinity')
min_pair = None

# loop over inputs
length = len(inp)
for i in xrange(length):
    for j in xrange(i+1, length):
        point1 = inp[i]
        point2 = inp[j]

        if math.hypot(point1[0] - point2[0], point1[1] - point2[0]) < min_distance:
            min_pair = [point1, point2]

once the loops are done, min_pair should be the pair with the smallest distance.

Using float() to parse the text leaves room for improvement.

math.hypot is about a third faster than calculating the distance in a handwritten python-function

Tags:

Python

Math