bugfix> python > 投稿

私の質問はこれに非常に似ています:numpy配列でN個の最大値のインデックスを取得する方法は?

しかし、私はそれらを見つけるのと同じ順序でインデックスを取得したいと思います。

その質問でマークされた例を正しい解決策として見てみましょう。

import numpy as np
arr = np.array([1, 3, 2, 4, 5])
arr.argsort()[-3:][::-1]
array([4, 3, 1])

代わりに私が探している結果は次のようになります:

array([1, 3, 4])

回答 2 件
  • numpy.argpartition() を使用する :

    k = 3
    np.argpartition(arr, len(arr) - k)[-k:]
    
    

    k を調整する  必要なものへのインデックス。

    注:返されるインデックスは「ソート順」であることが保証されていません-インデックス k を過ぎたものだけです  位置 k の値より大きい  ソートされた配列。

    注2:返されたインデックスが必要な場合ソートされる それ自体は、単に numpy.sort() を追加します  上記のコマンド:

    np.sort(np.argpartition(arr, len(arr) - k)[-k:])
    
    

    numpy.argpartition()  完全な sort よりも大幅にパフォーマンスが向上します  特に大きな arr の場合 。上記の例では、すべてではなく、選択したインデックスに対してのみフルソートを実行します。

  • おそらく a のサイズに少し依存します  および k  しかし、多くの場合、最速は partition を組み合わせているように見えます   flatnonzero と  または where

    >>> a = np.random.random(10000)
    >>> k = 5
    >>> 
    >>> timeit("np.flatnonzero(a >= np.partition(a, len(a) - k)[len(a) - k])", globals=globals(), number=10000)
    0.8328661819687113
    >>> timeit("np.sort(np.argpartition(a, len(a) - k)[len(a) - k:])", globals=globals(), number=10000)
    1.0577796879806556
    >>> np.flatnonzero(a >= np.partition(a, len(a) - k)[len(a) - k])
    array([2527, 4299, 5531, 6945, 7174])
    >>> np.sort(np.argpartition(a, len(a) - k)[len(a) - k:])
    array([2527, 4299, 5531, 6945, 7174])
    
    

    注1:これは、間接インデックス作成の大幅なパフォーマンスコストを強調しています。

    注2:ピボット要素のみを使用し、実際のパーティション percentile を破棄するため  理論的には少なくとも同じくらい速いはずですが、実際にはそれよりずっと遅いです。

あなたの答え