2012-11-28 5 views
25

Dovrebbe essere una domanda semplice, ma non riesco a trovare una risposta da nessuna parte. L'operatore ~ in python è documentato come operatore di inversione bit a bit. Belle. Ho notato comportamento apparentemente schizofrenico però, cioè:python tilde unario operatore come negazione numpy bool array

~True -> -2 
~1 -> -2 
~False -> -1 
~0 -> -1 
~numpy.array([True,False],dtype=int) -> array([-2,-1]) 
~numpy.array([True,False],dtype=bool) -> array([False,True]) 

Nei primi 4 esempi, posso vedere che pitone sta attuando (come documentato) ~x = -(x+1), con l'ingresso trattato come un int anche se è boolean . Quindi, per un booleano scalare, ~ non viene considerato come una negazione logica. Non che il comportamento sia identico su una matrice numpy definita con valori booleani con un tipo int.

Perché il ~ funziona come operatore di negazione logica su un array booleano (Nota: ~numpy.isfinite(numpy.inf) -> True?)?

È estremamente fastidioso che io debba utilizzare not() su uno scalare, ma not() non funzionerà per negare un array. Poi per un array, devo usare ~, ma ~ non funzionerà negare uno scalare ...

risposta

26

not viene attuato con il metodo speciale __nonzero__, che deve restituire uno o TrueFalse, così si può' t dare il risultato richiesto. Viene invece utilizzato l'operatore ~, implementato tramite il metodo speciale __not__. Per lo stesso motivo, & e | vengono utilizzati al posto di and e or.

PEP 335 finalizzato a consentire il sovraccarico di operatori booleani ma è stato respinto a causa di un sovraccarico eccessivo (ad esempio, complicherebbe le dichiarazioni if). PEP 225 suggerisce una sintassi generale per gli operatori "elementwise", che fornirebbe una soluzione più generale, ma è stata rinviata. Sembra che la situazione attuale, sebbene imbarazzante, non sia abbastanza dolorosa da forzare il cambiamento.

np.isfinite quando chiamato su uno scalare restituisce un valore di tipo np.bool_, non bool. np.bool_ è anche il tipo che si ottiene quando si estrae un valore scalare da una matrice di tipo booleano. Se si utilizza np.True_ e np.False_ al posto di True e False si otterrà un comportamento coerente sotto ~.

+0

Grazie ecatmur per la spiegazione, e soprattutto per menzionare '&' e '|'. Non ne sapevo nulla e usavo invece logico_e logico_or. –

+0

Sto usando 'numpy' per anni e fino ad ora non conoscevo lo scopo di quei costrutti apparentemente ridefiniti ma sottolineati come' np.False_'. Tutto ciò ha senso ora – dashesy