2012-03-05 10 views
5

アレイのブール値プロパティの端点を見つけるための(より一般的な)高速な方法よりも知っている人はいませんか?numpyでブール条件のエンドポイントを見つけるより高速な方法がありますか?

numpy.nonzero(a)[0] [ - 1]は、(dimension = 0)の最後の非ゼロ要素のインデックスであり、同様にnumpy.nonzero(a)[0] [0] is is最初の非ゼロ要素のインデックス

最初の要素または最後の要素のみを気にしていることが分かっている場合は、上記のように "nonzero"を実行するよりもメモリを少なくし、共通ケースの実行時間を短縮できます。たとえば、線形検索を使用する場合は、少なくとも適切な端で開始することができます(条件に一致する最後の値を見つけるために後方を検索する)。または、バイナリ検索を使用することもできます(たとえば、中間の要素が条件に一致する場合は、最初の要素が真である最後の要素を検索する必要はありません)。 これは、既存の実装が存在する可能性があると思われますが、そのようなものは見つかりませんでした。

+1

バイナリ検索は一般的には機能しません。 cnetral要素が 'True'の場合、左半分だけ見る必要があります - それは本当です。 cnetral要素が 'False'の場合、これは何も教えてくれません。 –

答えて

7

ブール値配列の最初のTrue要素は、argmaxを使用して検索できます。

a = np.array([False, False, True, True, True]) 
first_True = a.argmax() 
last_True = len(a) - 1 - a[::-1].argmax() 

あなたはFalseの値を見つけるためにargminを使用することができ、これは速くなるとゼロ以外の使用するよりも少ないメモリがかかりますが、これはaの長さが直線的です。線形より高速にしたい場合は、aが "ソート"されていることを知る必要があります。ブール値の配列の場合は、ブロックがFalseで、その後にすべてTrueが続くことを意味します。その場合、ソートされた検索を使ってFalseとTrueの境界を見つけることができます。

first_True = a.searchsorted(True, 'left') 
+0

良い説明! (そして、以前のコメントについては申し訳ありません。私はあなたの答え全体を読む前にそれを追加しました) –

+0

ブール値配列のargmaxの特殊な振る舞いは、[docs] ://docs.scipy.org/doc/numpy/reference/generated/numpy.argmax.html)。 – Trilarion

+0

ブール配列の特別な動作はありません。ドキュメントでは、「最大値が複数発生した場合、最初のオカレンスに対応するインデックスが返されます。 –

関連する問題