查找非排序Python浮点列表中最近元素索引的最快方法

时间:2015-05-18 05:46:40

标签: python arrays numpy

给定输入一个未排序的浮点数列表,找到最接近某个值的索引的最有效方法是什么?我想到了一些潜在的解决方案:

:用于:

x = random.sample([float(i) for i in range(1000000)], 1000000)

1)自己的功能:

def min_val(lst, val):
    min_i = None
    min_dist = 1000000.0
    for i, v in enumerate(lst):
        d = abs(v - val)
        if d < min_dist:
            min_dist = d
            min_i = i
    return min_i

结果:

%timeit min_val(x, 5000.56)
100 loops, best of 3: 11.5 ms per loop

2)敏感

%timeit min(range(len(x)), key=lambda i: abs(x[i]-5000.56))
100 loops, best of 3: 16.8 ms per loop

3)Numpy(包括转换)

%timeit np.abs(np.array(x)-5000.56).argmin()
100 loops, best of 3: 3.88 ms per loop

从该测试开始,似乎将列表转换为numpy数组是最佳解决方案。但是有两个问题浮现在脑海中:

  1. 这确实是一个现实的比较吗?
  2. numpy解决方案是用Python实现这一目标的最快方法吗?

1 个答案:

答案 0 :(得分:0)

考虑来自QuickSort的partition algorithm。分区算法重新排列列表,使得枢轴元素在调用后位于其最终位置。根据数据透视表的值,您可以对数组中可能包含最接近目标的元素的部分进行分区。一旦你找到了你想要的元素,或者你有一个包含你元素的长度为1的分区,你就完成了。

您要解决的一般问题是selection problem

在您的问题中,您想知道要使用哪种数组/列表实现,这将对性能产生影响。更重要的因素是搜索算法,而不是列表/数组表示。

根据@Andrzej的评论进行编辑

啊,那我误解了你的问题。严格地说,线性搜索总是O(n),因此无论基础数据结构如何,Big-Oh分析范围内的效率都是相同的。这里的问题是,对于线性搜索,您需要一个漂亮的简单数据结构,以使运行时性能尽可能好。

Python列表是对象的引用数组,而(据我所知)Numpy数组是一个连续的对象数组。 Numpy数组的性能会更好,因为它不需要取消引用对象来获取值。

对于Python列表与Numpy数组,您的比较技术似乎是合理的。我不愿意说Numpy数组是解决问题的最快方法,但它应该比Python列表表现更好。