2

複数のターゲットに近いソート済み配列 A内のすべての値インデックスを見つける良い方法はありますか? numpy.searchsorted() を使用すると、複数のターゲットに近いインデックスを効率的に見つけることができます: 最も近い値を見つけて、Python で配列のインデックスを返す ただし、配列 A に繰り返し値がある場合、このメソッドはインデックスの 1 つだけを返します。すべての可能なインデックスではなく。たとえば、次のような配列です。

A = array([    1. ,     2. ,     3. ,     3. ,     3.1,     4. ,    50. ,
          60. ,    70. ,    80. ,    90. ,   100.1,   110. ,   120. ,
         999. ,  1000. ])
targets=[3, 100]

idx = [2, 11] を返しますが、[[2,3],11] を返したいのですが、idx をループして [A==A[idx[0]] のようなブール値のインデックスを取得するだけです。 ],A==A[idx[1]],...] ただし、ターゲット配列が非常に大きい場合、これは非常に非効率的です。

1 つのことは、最初に numpy.unique() を使用して配列の一意のセットを見つけることができたことです。すべて同じ値を見つける。次に、その一意の配列で searchsorted() を実行すると、時間を節約できます。次に、このインデックスを使用して、すべて同じ値を見つけることができます。

以下に例を示します。

def find_closest_multiTargets_inSortred(A,targets):
        #A must be sorted
    idx = A.searchsorted(targets)
    idx = npy.clip(idx, 1, len(A)-1)
    left = A[idx-1]
    right = A[idx]
    idx -= targets - left < right - targets
    return idx

def find_closest_multiTargets_Allrepeats(A,targets):
    ua=npy.unique(A)
    _uaIdxs=find_closest_multiTargets_inSortred(ua, targets)
    return [npy.where(A==ua[_i]) for _i in _uaIdxs]

>>> find_closest_multiTargets_Allrepeats([5.1,5.5,4,1,2.3,5.1,6],[2,5])
[(array([4]),), (array([0, 5]),)]

len(ua)<<len(A)Aで最も近いものを直接見つけようとするよりもはるかに効率的だと思います。代替の unique() を作成して、A の各一意の値のインデックス リストを取得できる場合 ([[インデックスの値は ua[0]]、[インデックスの値は ua[2]]...])。それははるかに効率的です:

def find_closest_multiTargets_Allrepeats2(A,targets):
    ua,idxList=npy.unique2(A)
    _uaIdxs=find_closest_multiTargets_inSortred(ua, targets)
    return idxList[_uaIdxs]

しかし、 unique2()が期待することを実行できるものがあるかどうかはわかりません。searchsorted 以外のより効率的な方法で同じ結果を得ることができる、まったく異なるアルゴリズムが他にもあるかもしれません。

簡単にするために、A がソートされていると仮定します。ソートされていない配列 A の場合、常に最初に argsort できます。

これを行うためのより効率的な方法を提供できる人はいますか?

ありがとう!

4

2 に答える 2

1

次のことができます。

a = np.array([1., 2., 3., 3., 3.1, 4., 50., 60., 70., 80., 90., 100.1, 110., 120., 999., 1000.])
t = np.array([3, 100])
  • ペアごとの距離を計算します。

    d = np.abs(np.subtract.outer(a, t))
    

  • 最も近い値を見つける:

    asort = np.argsort(d, axis=0)
    

  • 最も近いインデックスと最も近い値を取得します。
    ind = np.arange(a.shape[0])
    print(ind[asort][0])
    #array([ 2, 11], dtype=int64)
    print(a[asort][0]) #array([ 3. , 100.1])

[i]最後のステップ以外で他のインデックスを使用する[0]と、i 番目に近い値が得られることに注意してください... を使用[0]すると、最も近い値が得られます。

于 2014-07-01T21:28:27.483 に答える
0

numpy.in1d(A, idx) は、あなたが望むように見えることを行います。

于 2014-07-01T20:57:31.397 に答える