2013-08-02 2 views
14

Я хочу повторить булевы NA значения, как они ведут себя в R:Как сделать булеву алгебру по отсутствующим значениям?

NA является допустимым логическим объектом. Если компонент x или y является NA, результатом будет NA, если результат неоднозначен. Другими словами NA & TRUE оценивает значение NA, но NA & FALSE оценивает значение FALSE. http://stat.ethz.ch/R-manual/R-devel/library/base/html/Logic.html

Я видел None рекомендую для отсутствующих значений, но Python преобразует None в False при оценке логических выражений и вычисляет None or False к False. Разумеется, результат должен был быть None, так как не было сделано никаких выводов, учитывая недостающее значение.

Как достичь этого в Python?

EDIT Принято ответа правильно вычисляет с поразрядными логическими операторами, но для достижения того же поведения с логическими операциями not, or и and, кажется, требует изменений в языке программирования Python.

+0

'(лямбда х: | ~ х) (NA)'? – SingleNegationElimination

ответ

9

Как уже говорилось, вы можете определить свой собственный класс.

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

Использование:

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

Мне нравится ваш ответ, но вы все еще не можете оценить 'NA или True' на' True'? В ваших примерах используются побитовые операторы. – user2646234

+1

Насколько я знаю, невозможно переопределить «или» и «и». 'NA или True' интерпретируется как' (NA .__ nonzero __() == True) | (True .__ ненулевой __() == True) '. Пожалуйста, поправьте меня, если я ошибаюсь; Я хотел бы ошибаться в этом. http://docs.python.org/2/reference/datamodel.html#emulating-numeric-types –

6

Вы можете сделать это, создав класс и опрокинув логические методы работы.

>>> 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' дает' False'. Наверное, не желаемое поведение. Кроме того, может быть полезно сделать что-то в том, что 'if NA: do_whatever()' выполняет 'do_whatever()' без предупреждения. – user2357112

+0

@ user2357112 Я обратился к этим двум пунктам в своем ответе –

+0

@ Chris Barker Да, ваш ответ намного более совершенен. Я просто давал прыжок. – Brien

Смежные вопросы