ValueError:複数の要素を持つ配列の真理値があいまいです。a.any()またはa.all()を使用します


221

さまざまな問題を引き起こしているコードの論理的なバグを発見しました。私はうっかりやっていたビット単位のANDの代わりに、論理AND

私はコードを次のように変更しました:

r = mlab.csv2rec(datafile, delimiter=',', names=COL_HEADERS)
mask = ((r["dt"] >= startdate) & (r["dt"] <= enddate))
selected = r[mask]

に:

r = mlab.csv2rec(datafile, delimiter=',', names=COL_HEADERS)
mask = ((r["dt"] >= startdate) and (r["dt"] <= enddate))
selected = r[mask]

驚いたことに、私はかなり不可解なエラーメッセージを受け取りました。

ValueError:複数の要素を持つ配列の真理値があいまいです。a.any()またはa.all()を使用します

ビット単位の演算を使用すると、同様のエラーが出力されなかったのはなぜですか?これを修正するにはどうすればよいですか?


1
Pandas もこれに関するドキュメント提供しています
Greg

回答:


164

rnumpy(rec)配列です。これr["dt"] >= startdateも(ブール)配列です。numpy配列の場合、&演算は2つのブール配列の要素ごとのANDを返します。

numpyの開発者は、ブール値のコンテキストで配列を評価するために誰も一般に理解の方法がなかったと感じた。それが意味する可能性がTrueあれば任意の要素がある True、またはそれが意味する可能性がTrueあれば、すべての要素があるTrue、またはTrue配列の長さがゼロでない場合は名前だけ3に、可能性。

ユーザーごとにニーズや想定が異なる可能性があるため、NumPy開発者は推測を拒否し、代わりにブールコンテキストで配列を評価しようとするたびにValueErrorを発生させることにしました。and2つのnumpy配列に適用すると、2つの配列がブールコンテキストで評価されます(__bool__Python3またはPython2で呼び出すことにより__nonzero__)。

元のコード

mask = ((r["dt"] >= startdate) & (r["dt"] <= enddate))
selected = r[mask]

正しいようです。ただし、必要な場合はand、代わりにまたはをa and b使用します。(a-b).any()(a-b).all()


2
あなたが正しい。元のコードは正しかった。バグはコードのどこかにあるようです。
Homunculus Reticulli

2
素晴らしい説明。ただし、NumPyは非常に非効率的です。両方のブール配列を完全に評価しますが、効率的な実装では1つのループ内でcond1(i)&& cond2(i)を評価し、cond1がtrueでない限りcond2をスキップします。
Joachim W

@JoachimWuttke:np.allnp.anyは短絡できますが、それに渡される引数は、短絡する前に評価されるnp.allnp.any、または短絡する可能性があります。よりよくするには、現在、これに似た特殊なC / Cythonコードを記述する必要があります。
unutbu 2013

47

私は同じ問題を抱えていました(つまり、複数条件でのインデックス作成、ここでは特定の日付範囲のデータを検索しています)。(a-b).any()あるいは(a-b).all()、少なくとも私にとっては、働いていないように見えます。

または、目的の機能に対して完全に機能する別の解決策を見つけました(複数の要素を持つ配列の真理値は、配列にインデックスを付けるときにあいまいです)。

上記の推奨コードを使用する代わりに、単純にa numpy.logical_and(a,b)を使用するだけで十分です。ここでは、コードを次のように書き直すことができます

selected  = r[numpy.logical_and(r["dt"] >= startdate, r["dt"] <= enddate)]

34

例外の理由は、and暗黙的にを呼び出すためboolです。最初に左のオペランド、True次に(左のオペランドがの場合)次に右のオペランド。したがって、x and yと同等bool(x) and bool(y)です。

ただし、boolon a numpy.ndarray(複数の要素が含まれている場合)は、見た例外をスローします。

>>> import numpy as np
>>> arr = np.array([1, 2, 3])
>>> bool(arr)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

bool()呼び出しは、暗黙的であるandが、また、中ifwhileor、次の例のいずれも失敗しますので。

>>> arr and arr
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

>>> if arr: pass
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

>>> while arr: pass
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

>>> arr or arr
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Pythonにboolは、呼び出しを非表示にする関数やステートメントが他にもあります。たとえば、を2 < x < 10記述するもう1つの方法にすぎません2 < x and x < 10。とandを呼びますboolbool(2 < x) and bool(x < 10)

要素ごとの同等物andnp.logical_and関数であり、同様にのnp.logical_or同等物として使用できますor

ブール配列の場合-などを比較<<===!=>=>numpyのアレイ上のブールnumpyの配列を返す-あなたはまた、使用することができます要素ごとのビット単位の機能(および演算子): np.bitwise_and&演算子)

>>> np.logical_and(arr > 1, arr < 3)
array([False,  True, False], dtype=bool)

>>> np.bitwise_and(arr > 1, arr < 3)
array([False,  True, False], dtype=bool)

>>> (arr > 1) & (arr < 3)
array([False,  True, False], dtype=bool)

およびbitwise_or|演算子):

>>> np.logical_or(arr <= 1, arr >= 3)
array([ True, False,  True], dtype=bool)

>>> np.bitwise_or(arr <= 1, arr >= 3)
array([ True, False,  True], dtype=bool)

>>> (arr <= 1) | (arr >= 3)
array([ True, False,  True], dtype=bool)

論理関数とバイナリ関数の完全なリストは、NumPyのドキュメントにあります。


2

pandas私の問題を解決したもので作業する場合、私がNA値を持っているときに計算をしようとしていたことが解決策でした:

df = df.dropna()

そしてその後、失敗した計算。


0

この型付きのエラーメッセージif-statementは、たとえばboolやintなどの配列がある場所で比較が行われているときにも表示されます。例をご覧ください:

... code snippet ...

if dataset == bool:
    ....

... code snippet ...

この句はデータセットを配列として持ち、boolは「オープンドア」です... TrueまたはFalse

関数がでラップされているtry-statement場合はexcept Exception as error:、エラータイプのないメッセージが表示されます。

複数の要素を持つ配列の真理値があいまいです。a.any()またはa.all()を使用します


-6

this => numpy.array(r)またはnumpy.array(yourvariable)に続けて、必要なものを比較するコマンドを試してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.