2012-09-28 5 views
11

Sto provando a inserire tutti gli elementi di rbs in un nuovo array se gli elementi in var (un altro array numpy) sono> = 0 e < = .1. Tuttavia quando provo il seguente codice ottengo questo errore:Il valore di verità di un array con più di un elemento è ambiguo quando si tenta di indicizzare un array

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

rbs = [ish[4] for ish in realbooks] 
for book in realbooks: 
    var -= float(str(book[0]).replace(":", "")) 
    bidsred = rbs[(var <= .1) and (var >=0)] 

tutte le idee su quello che sto facendo male?

+0

Quale riga causa l'errore? Inoltre, si prega di formattare il codice in modo che venga effettivamente eseguito. –

+0

Sarebbe utile se si stampasse il valore di var. Ad una ipotesi, il problema è nella variabile stringa/float/text sostituita che stai decrementando ... Come sono i dati originali che richiederebbero una serie di operazioni? – abought

risposta

27

Come ti ho detto in un commento ad una precedente risposta, è necessario utilizzare:

c[a & b] 

o

c[np.logical_and(a, b)] 

Il motivo è che la parola chiave and viene utilizzata da Python per verificare tra due valori booleani. Come può un array essere un booleano? Se il 75% dei suoi articoli è True, è True o False? Pertanto, numpy si rifiuta di confrontare i due.

Quindi, è necessario utilizzare la funzione logica per confrontare due array booleani su base elemento per elemento (np.logical_and) o l'operatore binario &.

Inoltre, per scopi di indicizzazione, è davvero necessario un array booleano con le stesse dimensioni dell'array che si sta indicizzando. E deve essere un array, non è possibile utilizzare un elenco di True/False invece: Il motivo è che l'utilizzo di un array booleano indica a NumPy quale elemento restituire. Se si utilizza un elenco di True/False, NumPy interpreterà questo come un elenco di 1/0 come numeri interi, ovvero indici, il che significa che si ottiene il secondo o il primo elemento dell'array. Non quello che vuoi.

Ora, come si può intuire, se si desidera utilizzare due array booleani a o b per l'indicizzazione, scegliendo gli elementi per i quali sia a o b è vero, devi usare

c[np.logical_or(a,b)] 

o

c[a | b] 
8

In genere questo messaggio di errore quando si tenta di utilizzare Python operatori booleani (not, and, or) sulle espressioni di confronto che coinvolgono le matrici numpy, per esempio

>>> x = np.arange(-5, 5) 
>>> (x > -2) and (x < 2) 
Traceback (most recent call last): 
    File "<ipython-input-6-475a0a26e11c>", line 1, in <module> 
    (x > -2) and (x < 2) 
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 

Questo perché tali confronti, a differenza di altri confronti in Python, creano array di booleani anziché booleani singoli (ma forse si sapevano già che):

>>> x > -2 
array([False, False, False, False, True, True, True, True, True, True], dtype=bool) 
>>> x < 2 
array([ True, True, True, True, True, True, True, False, False, False], dtype=bool) 

parte della soluzione al vostro problema probabilmente per sostituire and per np.logical_and, che trasmette l'operazione AND su due matrici di np.bool.

>>> np.logical_and(x > -2, x < 2) 
array([False, False, False, False, True, True, True, False, False, False], dtype=bool) 
>>> x[np.logical_and(x > -2, x < 2)] 
array([-1, 0, 1]) 

Tuttavia, tali array di booleani non possono essere utilizzati per indicizzare in liste Python ordinari, quindi è necessario convertire in un array:

rbs = np.array([ish[4] for ish in realbooks])