2011-11-03 7 views
6

Apprezzerei se qualcuno potesse aiutarmi con questo (e spiegando cosa sta succedendo).Numpy: ho bisogno di una mano per capire cosa succede con l'operatore "in"

Questo funziona:

>>> from numpy import array 
>>> a = array((2, 1)) 
>>> b = array((3, 3)) 
>>> l = [a, b] 
>>> a in l 
True 

Ma questo non lo fa:

>>> c = array((2, 1)) 
>>> c in l 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 

Il comportamento vorrei replicare è:

>>> x = (2, 1) 
>>> y = (3, 3) 
>>> l2 = [x, y] 
>>> z = (2, 1) 
>>> z in l2 
True 

Nota che quanto sopra funziona anche con mutevoli oggetti:

>>> x = [2, 1] 
>>> y = [3, 3] 
>>> l2 = [x, y] 
>>> z = [2, 1] 
>>> z in l2 
True 

Ovviamente, sapendo che:

>>> (a < b).all() 
True 

ho provato (e fallito):

>>> (c in l).all() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 

risposta

6

Python rende la scelta che bool([False,True]) è True perché (si dice) una lista non empy ha valore booleano Vero.

Numpy effettua la scelta che bool(np.array([False, True])) dovrebbe generare un errore ValueError. Numpy è stato progettato dal punto di vista che alcuni utenti potrebbero voler sapere se qualsiasi degli elementi nella matrice sono True, mentre altri potrebbero voler sapere se tutti gli gli elementi nella matrice sono True. Poiché gli utenti possono avere desideri in conflitto, NumPy rifiuta di indovinare. Solleva un'eccezione ValueError e suggerisce di utilizzare np.any o np.all (sebbene se si desideri replicare il comportamento simile a Python, si utilizzerà len).

Quando si valuta c in l, Python confronta c con ogni elemento in l iniziando con a. Valuta bool(c==a). Otteniamo bool(np.array([True True])), che genera un errore ValueE (per la ragione sopra descritta).

Dal momento che Numpy rifiuta di indovinare, devi essere specifico. Suggerisco:

import numpy as np 
a=np.array((2,1)) 
b=np.array((3,3)) 
c=np.array((2,1)) 
l=[a,b] 
print(any(np.all(c==elt) for elt in l)) 
# True 
+0

Molto utile, voi (+1) grazie ... Non sto ancora ricevendo il motivo per cui 'a in l' ottiene un risultato diverso da quello' c in l' però. In entrambi i casi il comando dovrebbe testare una matrice numpy in una lista standard ... qual è la differenza che non riesco a vedere? – mac

+0

@mac: Questa è una grande domanda e non conosco la risposta. [I documenti dicono] (http://docs.python.org/reference/expressions.html#notin), "Per i tipi lista e tupla, x in y è vero se e solo se esiste un indice i tale che x == y [i] è vero. ", ma' bool (a == l [0]) 'solleva un'eccezione ValueError e tuttavia 'a in l' restituisce True. Non so come risolvere questa (apparente) contraddizione. – unutbu

+0

E per aggiungere al mistero, 'b in l' solleva un errore ValueError ... – unutbu

Problemi correlati