web-dev-qa-db-ja.com

numpy配列で要素ごとのブール演算を実行する方法

たとえば、40〜60の値を持つ要素をマスクするマスクを作成します。

foo = np.asanyarray(range(100))
mask = (foo < 40).__or__(foo > 60)

これは見苦しいだけで、書くことはできません。

(foo < 40) or (foo > 60)

私が終わるので:

  ValueError Traceback (most recent call last)
  ...
  ----> 1 (foo < 40) or (foo > 60)
  ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

見栄えの良いコードを持つnumpy配列で要素ごとのブール演算を行う標準的な方法はありますか?

46
jb.

これを試しましたか?

mask = (foo < 40) | (foo > 60)

注:__or__オブジェクトのメソッドは、ビット単位のor演算子をオーバーロードします(|)ブールor演算子ではありません。

70
jcollado

あなたの例のようにブール値のみで比較する場合は、Jcolladoが提案するビット単位のOR演算子_|_を使用できます。ただし、 mask = (foo < 40) | overrideなどの非ブール値を使用してください。overrideがFalse、True、1、または0であることが保証されている限り、問題ありません。

より一般的なのは、numpyの比較セット演算子_np.any_および_np.all_の使用です。このスニペットは、35から45までのすべての値を返します。これらの値は、40より小さいか、3の倍数ではありません。

_import numpy as np
foo = np.arange(35, 46)
mask = np.any([(foo < 40), (foo % 3)], axis=0)
print foo[mask]
OUTPUT: array([35, 36, 37, 38, 39, 40, 41, 43, 44])
_

_|_ほどではありませんが、質問のコードよりも優れています。

15
dirkjot

numpy logical operations を使用できます。あなたの例では:

np.logical_or(foo < 40, foo > 60)
9
ViennaMike

要素ごとの否定には~を使用できることに注意してください。

arr = np.array([False, True])
~arr

OUTPUT: array([ True, False], dtype=bool)

また、&は要素ごとにandを行います

arr_1 = np.array([False, False, True, True])
arr_2 = np.array([False, True, False, True])

arr_1 & arr_2

OUTPUT:   array([False, False, False,  True], dtype=bool)

これらはPandas Seriesでも動作します

ser_1 = pd.Series([False, False, True, True])
ser_2 = pd.Series([False, True, False, True])

ser_1 & ser_2

OUTPUT:
0    False
1    False
2    False
3     True
dtype: bool
3
Roko Mijic