Python 向量中元素之间的最小距离

Python 向量中元素之间的最小距离,python,numpy,Python,Numpy,我需要数组元素之间的最小距离 我做到了: numpy.min(numpy.ediff1d(numpy.sort(x))) 有没有更好/更高效/更优雅/更快的方法?您目前的方法绝对是最佳的。通过先排序,可以减少每个元素之间的空间,ediff1d将返回一个差异数组。这里有一个建议: 由于我们知道差异必须为正,因为我们有一个升序排序,所以我们可以手动实现ediff1d,并在差异为零时包含一个中断。这样,如果您有排序数组x: [1,1,2,3,4,5,6,7,…,n] 您的ediff1d函数没有遍历n

我需要数组元素之间的最小距离

我做到了:

numpy.min(numpy.ediff1d(numpy.sort(x)))

有没有更好/更高效/更优雅/更快的方法?您目前的方法绝对是最佳的。通过先排序,可以减少每个元素之间的空间,
ediff1d
将返回一个差异数组。这里有一个建议:

由于我们知道差异必须为正,因为我们有一个升序排序,所以我们可以手动实现
ediff1d
,并在差异为零时包含一个中断。这样,如果您有排序数组
x

[1,1,2,3,4,5,6,7,…,n]

您的
ediff1d
函数没有遍历n个元素,而是提前中断,只覆盖前两个元素,返回
[0]
。这也减少了差异数组的大小,减少了
min
调用所需的迭代次数

下面是一个不使用numpy的示例:

x = [1, 12, 3, 8, 4, 1, 4, 9, 1, 29, 210, 313, 12]

def ediff1d_custom(x):
    darr = []

    for i in xrange(len(x)):
        if i != len(x) - 1:
            diff = x[i + 1] - x[i]
            darr.append(diff)

            if diff == 0:
                break

    return darr

print min(ediff1d_custom(sorted(x))) # prints 0

如果您追求绝对速度,以下是一些计时:

In [13]: a = np.random.rand(1000)

In [14]: %timeit np.sort(a)
10000 loops, best of 3: 31.9 us per loop

In [15]: %timeit np.ediff1d(a)
100000 loops, best of 3: 15.2 us per loop

In [16]: %timeit np.diff(a)
100000 loops, best of 3: 7.76 us per loop

In [17]: %timeit np.min(a)
100000 loops, best of 3: 3.19 us per loop

In [18]: %timeit np.unique(a)
10000 loops, best of 3: 53.8 us per loop
unique
的计时是希望它能以相对较快的速度进行
排序
,并且如果unique数组的长度比数组本身短(这意味着您的答案是
0
),您可以在不调用
diff
min
的情况下提前爆发。但是
unique
的开销比任何收益都要大

因此,我能提供的唯一潜在改进似乎是将
ediff1d
替换为
diff

In [19]: %timeit np.min(np.diff(np.sort(a)))
10000 loops, best of 3: 47.7 us per loop

In [20]: %timeit np.min(np.ediff1d(np.sort(a)))
10000 loops, best of 3: 57.1 us per loop

您想要更优雅还是更高效?;-)好吧,我想在我的情况下,我需要的是快速有趣,但过度杀伤力,而不是我所需要的。我需要的是单个1d数组中的值。除非预期的最小值实际为零,否则这将比OP的现有解决方案慢得多。这是怎么回事?这是因为numpy是预编译的吗?@DanielLi,而且数组(通常)在连续内存中,而不是在动态列表中。请参见
x
在执行此操作之前仍必须进行排序,因为这基本上只是非numpy
min(ediff1d(x))
交互测试。我原以为
ediff1d
diff
快,因为它适用于1d数组,但显然
diff
更快。
In [19]: %timeit np.min(np.diff(np.sort(a)))
10000 loops, best of 3: 47.7 us per loop

In [20]: %timeit np.min(np.ediff1d(np.sort(a)))
10000 loops, best of 3: 57.1 us per loop