ValueError: Birden fazla öğeye sahip bir dizinin doğruluk değeri belirsiz. A.any () veya a.all () kullanın


222

Kodumda her türlü soruna neden olan mantıklı bir hata keşfettim. Yanlışlıkla bitsel yapıyordum VE mantıksal bir AND yerine .

Kodu değiştirdim:

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

TO:

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

Şaşırtıcı bir şekilde, oldukça şifreli hata mesajını aldım:

ValueError: Birden fazla öğeye sahip bir dizinin doğruluk değeri belirsiz. A.any () veya a.all () kullanın

Bitsel bir işlem kullandığımda neden benzer bir hata oluşmadı - ve bunu nasıl düzeltirim?


1
Pandalar bunun için de belgeler sunuyor
Greg

Yanıtlar:


164

rbir numpy (rec) dizisidir. Aynı r["dt"] >= startdatezamanda (boolean) bir dizi. &Numpy diziler için, işlem iki boolean dizinin elemanını -ve döner.

Anlamına gelebilir: NumPy geliştiriciler yaygın bir şekilde boolean bağlamında bir dizi değerlendirmek için bir yol anlaşılacaktır hissetti TrueEğer herhangi bir elemandır True, ya da anlamına gelebilir True, eğer tüm unsurları True, ya da Truebir dizi sıfır olmayan bir uzunlukta ise, sadece üç isim olasılık.

Farklı kullanıcıların farklı ihtiyaçları ve farklı varsayımları olabileceğinden, NumPy geliştiricileri tahmin etmeyi reddetti ve bunun yerine bir diziyi boole bağlamında değerlendirmeye çalıştığında bir ValueError oluşturmaya karar verdiler. andİki numpy dizisine uygulamak , iki dizinin boolean bağlamında değerlendirilmesine neden olur ( __bool__Python3 veya __nonzero__Python2'de çağrılarak).

Orijinal kodunuz

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

doğru görünüyor. Ancak, isterseniz veya kullanmak andyerine .a and b(a-b).any()(a-b).all()


2
Haklısın. Orijinal kod doğruydu. Hata, kodda başka bir yerde yatıyor gibi görünüyor.
Homunculus Reticulli

2
Mükemmel açıklama. Bununla birlikte, NumPy'nin oldukça verimsiz olduğu anlamına gelir: her iki boole dizisini de tam olarak değerlendirirken, verimli bir uygulama tek bir döngü içinde cond1 (i) && cond2 (i) 'yi değerlendirir ve cond1 doğru olmadığı sürece cond2'yi atlar.
Joachim W

@JoachimWuttke: Her ne kadar np.allve np.anykısa devre yeteneğine sahip, kendisine iletilen bağımsız değişken önce değerlendirilir np.allveya np.anykısa devre şansı vardır. Şu anda daha iyisini yapmak için buna benzer özel C / Cython kodu yazmanız gerekir .
unutbu

47

Aynı sorunu yaşadım (yani çoklu koşullarla indeksleme, burada belirli bir tarih aralığında veri bulma). En azından benim için çalışmıyor (a-b).any()ya (a-b).all()da çalışmıyor gibi görünüyor.

Alternatif olarak, benim istenen işlevsellik için mükemmel bir şekilde çalışan başka bir çözüm buldum (Bir diziyi dizine eklemeye çalışırken birden fazla öğeye sahip bir dizinin gerçek değeri belirsizdir ).

Yukarıda önerilen kodu kullanmak yerine, sadece bir kullanmak numpy.logical_and(a,b)işe yarayacaktır. Burada kodu şu şekilde yeniden yazmak isteyebilirsiniz:

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

34

İstisna nedeni, anddolaylı olarak çağırıyor olmasıdır bool. Önce sol işlenende ve (sol işlenen ise True) sonra sağ işlenende. Yani buna x and yeşdeğerdir bool(x) and bool(y).

Ancak, boola numpy.ndarrayöğesinde (birden fazla öğe varsa) gördüğünüz istisnayı atar:

>>> 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()Çağrı örtülü olduğu and, aynı zamanda içinde if, while, or, Aşağıdaki örneklerin herhangi ayrıca başarısız olur böylece:

>>> 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'da boolaramaları gizleyen daha fazla işlev ve ifade var , örneğin 2 < x < 10sadece başka bir yazma yolu 2 < x and x < 10. Ve andarayacak bool: bool(2 < x) and bool(x < 10).

Öğeye göre eşdeğer andolacağını np.logical_andbenzer şunu kullanabilirsiniz, fonksiyon np.logical_oriçin eşdeğer olarak or.

Boolean diziler için - ve karşılaştırmalar gibi <, <=, ==, !=, >=ve >numpy üzerinde diziler boolean NumPy diziler dönmek - Ayrıca kullanabilirsiniz öğeye göre bitsel fonksiyonları (ve operatörleri): np.bitwise_and( &operatör)

>>> 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)

ve bitwise_or( |operatör):

>>> 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)

Mantıksal ve ikili işlevlerin tam bir listesi NumPy belgelerinde bulunabilir:


2

pandasbenim için sorunu çözen ne ile çalışırsanız ben NA değerleri vardı hesaplamalar yapmaya çalışıyordu, çözüm çalıştırmak oldu:

df = df.dropna()

Ve bundan sonra başarısız olan hesaplama.


0

Bu yazılan hata mesajı if-statement, bir dizi ve örneğin bir bool veya int olduğunda karşılaştırma yapılırken de gösterilir . Örneğin bakınız:

... code snippet ...

if dataset == bool:
    ....

... code snippet ...

Bu madde dizi olarak veri kümesi vardır ve bool euhm "açık kapı" ... Trueveya False.

İşlev bir içine sarılırsa , hata türü olmadan iletiyle try-statementbirlikte alırsınız except Exception as error::

Birden fazla öğeye sahip bir dizinin gerçek değeri belirsizdir. A.any () veya a.all () kullanın


-6

this => numpy.array (r) veya numpy.array (değişkeniniz) ardından da istediğinizi karşılaştırma komutunu deneyin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.