以更加pythonic的方式找到最近的邻居

时间:2015-12-06 09:45:48

标签: python numpy nearest-neighbor

A是一个点,P是一个点列表。 我想找到哪个点P [i]最接近A,即我希望找到P[i_0]

i_0 = argmin_i || A - P[i]||^2

我是这样做的:

import numpy as np

# P is a list of 4 points
P = [np.array([-1, 0, 7, 3]), np.array([5, -2, 8, 1]), np.array([0, 2, -3, 4]), np.array([-9, 11, 3, 4])]
A = np.array([1, 2, 3, 4])
distance = 1000000000     # better would be : +infinity
closest = None

for p in P:
  delta = sum((p - A)**2)
  if delta < distance:
    distance = delta
    closest = p

print closest    # the closest point to A among all the points in P

它有效,但如何以更短/更多的Pythonic方式执行此操作?

更常见的是在Python (甚至不使用Numpy),如何查找k_0使D[k_0] = min D[k]k_0 = argmin_k D[k]

4 个答案:

答案 0 :(得分:2)

实现您正在使用的相同算法的更Pythonic方法是使用<c:if test="${ myBool }"></if> 函数调用min来替换您的循环:

key

请注意,我使用closest = min(P, key=lambda p: sum((p - A)**2)) 进行取幂(**是Python中的binary-xor运算符。)

答案 1 :(得分:1)

作为单行的NumPy版本:

clostest = P[np.argmin(np.apply_along_axis(lambda p: np.sum((p - A) **2), 1, P))]

答案 2 :(得分:1)

numpy中完全矢量化的方法。类似于@MikeMüller,但使用numpy's broadcasting来避免lambda函数。

使用示例数据:

>>> P = [np.array([-1, 0, 7, 3]), np.array([5, -2, 8, 1]), np.array([0, 2, -3, 4]), np.array([-9, 11, 3, 4])]
>>> A = np.array([1, 2, 3, 4])

使P成为2D numpy数组:

>>> P = np.asarray(P)
>>> P
array([[-1,  0,  7,  3],
       [ 5, -2,  8,  1],
       [ 0,  2, -3,  4],
       [-9, 11,  3,  4]])

可以使用numpy在一行中计算:

>>> P[np.argmin(np.sum((P - A)**2, axis=1))]

请注意,P - AP.shape = (N, 4)A.shape = (4,)会将减法广播到PPi = Pi - A)的所有行。

对于小NP中的行数),pythonic方法可能更快。对于较大的N值,这应该明显更快。

答案 3 :(得分:0)

内置min的用法是这样的:

import math
p1 = [1,2]
plst = [[1,3], [10,10], [5,5]]
res = min(plst, key=lambda x: math.sqrt(pow(p1[0]-x[0], 2) + pow(p1[1]-x[1], 2)))
print res
[1, 3]

请注意,我刚刚使用了普通的python列表。