在Python数组中查找接近给定数字的多个值

4
使用Python 2.7,我有一个值数组,它的取值范围从约0.000到约360.000,这些值会出现多次。 我试图返回所有最接近147.010的数组索引(包括重复值),以便稍后可以使用每个索引。例如,来自一个数组的较小示例是:
array([  146.749,  147.249,  147.749,  146.749,  147.249,  147.749,  146.749,  147.263,  147.749,  146.472,  147.469,  148.471])

我正在寻找一个最接近 147.01 的索引的数组或列表,在这种情况下应该是: ```python [3, 6, 8] ``` ```javascript [2, 4, 5] ```
1, 4, 7, 10

我尝试过以下代码: min(range(len(array)), key=lambda i: abs(array[i]-some_value)) 但是该代码仅返回一个索引,而需要多个索引。我查看了相关问题和答案,但未找到类似的解决方法。感谢您的帮助。

问题在于您正在尝试多次查找最近的项目,那么您想要多少个呢?因为例如,每次我们找到最近的项目并将其从列表中删除,然后我们可以继续进行,以此类推,但必须设置一个限制,否则最终会得到所有值... - DevLounge
对于重复值,它很简单,就是所有与最近找到的值相等的值的索引,以此类推。 - DevLounge
你是在寻找最接近的n个数字,还是在一个区间[x-d, x+d]内的所有数字? - Markus
给定一个值数组,找到最接近用户给定数字的所有值。对于代码找到的所有接近值,返回这些索引。 - WXNerd
1
@WXNerd,“closest”是指字面上的“最近”,还是可能是“在某个容差范围内”?根据您提供的值来看,可能是后者。 - ptrj
在获得项目更多信息后,似乎更好的选择是将数组拆分成多个小数组,然后针对每个小数组从用户所给定的数字中找到最接近的值。 - WXNerd
3个回答

4
如果按照元素与枢轴的距离排序数组,那么您将能够获取前k个元素,这些元素是最接近您所查找的元素的。
def k_closest(sample, pivot, k):
    return sorted(sample, key=lambda i: abs(i - pivot))[:k]

例子:

>>> l = [1,2,3,4]
>>> k_closest(l, 3, 2)
[3,2]
>>> k_closest(l, 3, 3)
[3,2,4]

要同时获取元素的索引,可以这样做:
def k_closest(sample, pivot, k):
    return sorted(enumerate(sample), key=lambda (n, v): abs(v - pivot))[:k]

使用之前相同的元素运行它,我们得到:
>>> l = [1,2,3,4]
>>> k_closest(l, 3, 2)
[(2, 3), (1, 2)]
>>> k_closest(l, 3, 3)
[(2, 3), (1, 2), (3, 4)]

对于列表中的每个元组,第一个元素是原始数组中的索引,第二个元素是您实际感兴趣的数字。

如果您只需要索引,则可以稍微调整该函数:

import operator

def k_closest(sample, pivot, k):
    return map(operator.itemgetter(0), sorted(enumerate(sample), key=lambda (n, v): abs(v - pivot)))[:k]

使用原始输入,现在会给你

>>> k_closest(l, 3, 2)
[2, 1]
>>> k_closest(l, 3, 3)
[2, 1, 3]

0

您可以遍历并找到与最接近的值对应的键。然后将那些键对应的值附加到一个列表中。

new_array = map(lambda x: abs(x-some_value),my_array)

min_value=min(new_array)

现在找到新值的索引

my_keys = []
for i,val in enumerate(new_array):
    if val == min_value:
        my_keys.append(i)

最后创建您的输出列表。
my_answer=[]
for i in my_keys:
    my_answer.append(my_array[i])

当我尝试运行这段代码时,第一行出现了错误信息。我在 my_array 中输入了我的数组名称和我要查找的数字 some_value。我收到了消息:“TypeError:map()至少需要两个参数”。我不明白哪里缺少了参数。 - WXNerd
应该修复。您将不得不用您的变量替换变量名称。 - sebastianspiegel

0
如果你喜欢一行代码,可以使用 k = 147.01 然后你可以这样做:
print [i for i, v in enumerate(array) if abs(v - k) == min([abs(x - k) for x in array])]

输出:[1, 4]

它将打印出与k等距离的n个元素的索引。在您的列表中,索引7、10的元素不是等距离的,请再次确认这些数字。

编辑:让我们逐个查看,使用问题中的数组:

[146.749,  147.249,  147.749,  146.749,  147.249,  147.749,  146.749,  147.263,  147.749,  146.472,  147.469,  148.471]

索引为1、4、7、10的元素之间的距离:

index = 1,  abs(147.249 - 147.01) = 0.239
index = 4,  abs(147.249 - 147.01) = 0.239
index = 7,  abs(147.263 - 147.01) = 0.253
index = 10, abs(147.469 - 147.01) = 0.459

根据这些数字,索引为 1、4 的元素与 147.01 的距离比 7、10 更近。这难道不是你想要的吗?

我的数据中索引为7和10的数字是正确的。 - WXNerd
我的答案已更新,对这些元素进行了逐一比较。如果有遗漏的地方,请随时澄清。 - fips

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接