2013-08-02 19 views
14

voglio replicare booleane NA valori come si comportano in R:Come fare l'algebra booleana su valori mancanti?

NA è un oggetto logico valido. Dove un componente di x o y è NA, il risultato sarà NA se il risultato è ambiguo. In altre parole, NA & TRUE viene valutata in NA, ma NA & FALSE viene valutata in FALSE. http://stat.ethz.ch/R-manual/R-devel/library/base/html/Logic.html

Ho visto None essendo raccomandato per valori mancanti, ma Python converte None a False quando valutazione di espressioni booleane, e calcola None or False a False. Il risultato dovrebbe ovviamente essere None, in quanto non è possibile trarre conclusioni date il valore mancante.

Come ottengo ciò in Python?

EDIT risposta accettata calcola correttamente con bit a bit operatori booleani, ma per raggiungere lo stesso comportamento con gli operatori logici not, or e and, sembra richiedere una modifica nel linguaggio di programmazione Python.

+0

'(lambda x: x | ~ x) (NA)'? – SingleNegationElimination

risposta

9

Come altri hanno già detto, è possibile definire la propria classe.

class NA_(object): 
    instance = None # Singleton (so `val is NA` will work) 
    def __new__(self): 
     if NA_.instance is None: 
      NA_.instance = super(NA_, self).__new__(self) 
     return NA_.instance 
    def __str__(self): return "NA" 
    def __repr__(self): return "NA_()" 
    def __and__(self, other): 
     if self is other or other: 
      return self 
     else: 
      return other 
    __rand__ = __and__ 
    def __or__(self, other): 
     if self is other or other: 
      return other 
     else: 
      return self 
    __ror__ = __or__ 
    def __xor__(self, other): 
     return self 
    __rxor__ = __xor__ 
    def __eq__(self, other): 
     return self is other 
    __req__ = __eq__ 
    def __nonzero__(self): 
     raise TypeError("bool(NA) is undefined.") 
NA = NA_() 

Usa:

>>> print NA & NA 
NA 
>>> print NA & True 
NA 
>>> print NA & False 
False 
>>> print NA | True 
True 
>>> print NA | False 
NA 
>>> print NA | NA 
NA 
>>> print NA^True 
NA 
>>> print NA^NA 
NA 
>>> if NA: print 3 
... 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 28, in __nonzero__ 
TypeError: bool(NA) is undefined. 
>>> if NA & False: print 3 
... 
>>> 
>>> if NA | True: print 3 
... 
3 
>>> 
+1

Mi piace la tua risposta, ma non sei ancora in grado di valutare 'NA o True' su' True'? I tuoi esempi utilizzano operatori bit a bit. – user2646234

+1

Per quanto ne so, è impossibile sovrascrivere "o" e "e". 'NA o True' è interpretato come' (NA .__ nonzero __() == True) | (Vero .__ nonzero __() == Vero) '. Per favore correggimi se sbaglio; Mi piacerebbe sbagliarmi su questo. http://docs.python.org/2/reference/datamodel.html#emulating-numeric-types –

6

Si può fare questo con la creazione di una classe e sovrascrivendo i metodi di funzionamento booleani.

>>> class NA_type(object): 
     def __and__(self,other): 
       if other == True: 
         return self 
       else: 
         return False 
     def __str__(self): 
       return 'NA' 


>>> 
>>> NA = NA_type() 
>>> print NA & True 
NA 
>>> print NA & False 
False 
+2

'NA & NA' restituisce' False'. Probabilmente non è il comportamento desiderato. Inoltre, potrebbe essere utile fare qualcosa per il fatto che 'se NA: do_whatever()' esegue 'do_whatever()' senza nemmeno un avvertimento. – user2357112

+0

@ user2357112 Ho indirizzato questi due punti nella mia risposta –

+0

@Chris Barker Sì, la tua risposta è molto più completa. Stavo solo dando un punto di partenza. – Brien

Problemi correlati