Могут ли numpy / pandas обрабатывать логические операторы, работающие с нулевыми значениями? - PullRequest
0 голосов
/ 05 ноября 2018

Если я использую стандартные булевы операторы Python and / or / not, одна приятная особенность заключается в том, что они обрабатывают None так, как я бы логично ожидал. То есть не только

True and True == True
True and False == False

но также

True and None == None
False and None == False
True or None == True
False or None == None

Это соответствует логике, например, если A ложно, а B неизвестно, (A и B) все равно должно быть ложным, а (A или B) неизвестно.

Мне нужно было выполнить логические операции над кадрами данных Pandas с отсутствующими данными, и я надеялся, что смогу использовать ту же логику. Для логической логики на числовых массивах и рядах Панд нам нужно использовать побитовые операторы & / | / ~. Панды, кажется, имеют поведение, которое частично совпадает с and / or / not, но частично отличается. Короче говоря, кажется, что он возвращает False, когда значение логически должно быть неизвестно.

Например:

a = pd.Series([True,False,True,False])
b = pd.Series([True,True,None,None])

Тогда мы получим

> a & b
0     True
1    False
2    False
3    False
dtype: bool

и

> a | b
0     True
1     True
2     True
3    False

Я ожидаю, что на выходе a & b должна быть серия [True,False,None,False], а на выходе a | b должна быть серия [True,True,True,None]. Фактический результат соответствует ожидаемому, за исключением того, что возвращается False вместо пропущенных значений.

Наконец, ~b просто выдает ошибку TypeError:

TypeError: неверный тип операнда для унарного ~: 'NoneType'

, что кажется странным, поскольку & и | хотя бы частично работают.

Есть ли лучший способ для выполнения логической логики в этой ситуации? Это ошибка в Пандах?

Аналогичные тесты с массивами-пустышками просто дают ошибки типа, поэтому я предполагаю, что Pandas сам обрабатывает логику

1 Ответ

0 голосов
/ 05 ноября 2018

Вам может понадобиться что-то вроде этого:

c = pd.Series([x and y for x,y in zip(a,b)])

print(c)

Выход:

0     True
1    False
2     None
3    False

И соответственно для второго выражения:

d = pd.Series([x or y for x,y in zip(a,b)])

print(d)

Выход:

0    True
1    True
2    True
3    None

также посмотрите здесь для понимания операций and и &.


Если вы хотите and два столбца a и b кадра данных df, один из способов - определить функцию и применить ее к df:

df = pd.DataFrame({'a':[True,False,True,False], 'b':[True,True,None,None]})
def and_(row):
    return row['a'] and row['b']
df.loc[:, 'a_and_b'] = df.apply(and_, axis=1)
print(df)

Выход:

       a     b a_and_b
0   True  True    True
1  False  True   False
2   True  None    None
3  False  None   False
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...