3

配列の要素間の最小距離が必要です。

やった:

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

これを行うためのより良い/より効率的/よりエレガント/高速な方法はありますか?

4

3 に答える 3

4

あなたが完全なスピードを求めているなら、ここにいくつかのタイミングがあります:

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を期待していました。しかし、オーバーヘッドは、得られる利益以上のものです。sortdiffmin0unique

したがって、私が提供できる唯一の潜在的な改善は、次のものに置き換えること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
于 2013-04-11T17:18:20.330 に答える
2

あなたの現在のアプローチは間違いなく最適です。最初に並べ替えると、各要素間のスペースが減り、ediff1d差分配列が返されます。ここに提案があります:

昇順の並べ替えがあるため、差が正でなければならないことがわかっているため、ediff1d手動で実装して、差がゼロになるブレークを含めることができます。そうすれば、ソートされた配列がある場合x

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

n 個の要素を通過するのではなく、ediff1d関数は早期に中断し、最初の 2 つの要素のみをカバーして を返し[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
于 2013-04-11T16:26:07.780 に答える
0
try:
    min(x[i+1]-x[i] for i in xrange(0, len(x)-1))
except ValueError:
    print 'Array contains less than two values.'
于 2013-04-11T17:08:14.083 に答える