Python 3.x 如何找到;“最近的邻居”;在Python的列表中?

Python 3.x 如何找到;“最近的邻居”;在Python的列表中?,python-3.x,list,numpy,Python 3.x,List,Numpy,我的目标如下:给定一个数字列表(int.或float)(1D),我需要找到N个最接近的数字 这张名单上的每一个人。例如: 给定sample\u list=[1,8,14,15,17,100,35]和N=3,所需函数应返回[14,15,17]的列表,因为此列表中的3个“最近邻”是14,15和17 到目前为止,我已经通过以下方式解决了这个问题,被迫在我的方法中做出了一些妥协(在网上搜索解决方案失败后): 我决定对列表中的每个数字进行迭代,找到其N个“最近邻”。这些“最近邻”存储在一个新列表中,然后使

我的目标如下:给定一个数字列表(int.或float)(1D),我需要找到N个最接近
的数字 这张名单上的每一个人。例如:

给定
sample\u list=[1,8,14,15,17,100,35]
N=3
,所需函数应返回
[14,15,17]
的列表,因为此列表中的3个“最近邻”是14,15和17

到目前为止,我已经通过以下方式解决了这个问题,被迫在我的方法中做出了一些妥协(在网上搜索解决方案失败后):

我决定对列表中的每个数字进行迭代,找到其N个“最近邻”。这些“最近邻”存储在一个新列表中,然后使用函数与其他类似列表进行比较。由
numpy.diff
产生的金额最小的列表为获胜者

我的解决方案的基础是Geeksforgeks.org上提供的代码。使用
numpy.diff
函数的想法来自stackoverflow.com

我的(工作)怪物可以在下面找到:

将numpy导入为np
def find_nn_in_list_1D(用于搜索的列表,所需的邻居数):
list\u iterator=list\u for\u search.copy()
list_mod=list_for_search.copy()
邻居存储列表=[]
邻居评估分数=999\u 999\u 999
对于列表迭代器中的数字:
近邻=列表模式[min(范围(len(列表模式)),key=lambda i:abs(列表模式[i]-number))]
邻居\存储\列表。追加(邻居\无)
列表修改删除(邻居无)
对于范围内的num_邻居(需要num_邻居):
邻居=列表模式[min(范围(len(列表模式)),键=lambda i:abs(列表模式[i]-编号))]
邻居存储列表。追加(邻居)
列表模块删除(邻居)
邻居存储列表。排序()
如果邻居评估分数>abs(总和(np.diff(邻居存储列表)):
邻居评估分数=abs(总和(np.diff(邻居存储列表)))
最近的邻居列表=邻居存储列表。复制()
list_mod=list_for_search.copy()
邻居存储列表=[]
返回最近的邻居列表
我非常肯定有一个更好的方法来解决这个问题

即使它可以工作,我还是希望编写更好、更干净的代码

如果你有比我更好的解决方案,请在下面分享。谢谢你抽出时间

这会有用的-

import numpy as np

N = 3
X = np.array([1, 8, 14, 15, 17, 100, 35]).astype(np.float32)

d = np.abs(X[None, :] - X[:, None])
np.fill_diagonal(d, np.inf)

min_array = d.min(0)

par = np.argpartition(min_array, N)

print(X[par[:N]])
这给-

[14.15.17.]


首先,创建每对元素之间的差异矩阵。然后,您可以从中选择
n
最小差异,并使用它来查找要查找的元素的索引。只需确保掩盖矩阵的对角元素,因为它们总是为零(因为它们将表示每个点到自身的距离)。

如果对
numpy
没有特别的依赖关系,我们也可以通过一些理解来解决这个问题-

lst = [1, 8, 14, 15, 17, 100, 35]

#Make pairs and remove duplicates using a set
lst_pairs = set([tuple(sorted((x, y))) for x in lst for y in lst if x != y])

#Make a dictionary mapping a pair to distance
dist_dict = {k: k[1] - k[0] for k in lst_pairs}

#extract the top 3 by distance
nearest_n = sorted(dist_dict, key=lambda x: dist_dict[x])[:3]

#unpack the pairs to unique points
nearest_n_pts = set([pt for pair in nearest_n for pt in pair])

#nearest_n_pts is [14, 15, 17]

你好,阿南达!请您澄清一下par=np.argpartition(最小数组,N)。在那一行之前,我一直支持你,但我很难理解这个函数的作用。它可以找到输入中最小N个数字的索引<在这种情况下,code>par[:N]将是
[2,3,4]
,这意味着在
min\u数组中
最小的三个元素在索引
[2,3,4]
中。只需从原始代码< x>代码>中选择这些值,这就是你的解决方案。如果你的问题被解决了,请考虑通过接受答案来关闭它。