Почему ~pd.isnull() возвращает -2?

#python

#python

Вопрос:

Я проводил несколько быстрых тестов для обработки пропущенных значений и столкнулся с этим странным поведением. При просмотре ~pd.isnull(np.nan) я ожидаю, что он вернет False , но вместо этого он возвращает -2. Почему это?

Комментарии:

1. Ваши тесты будут более ценными, если вы тщательно проанализируете типы тестируемых данных.

Ответ №1:

Ваше замешательство оправдано, потому что этот странный результат для скаляра несовместим с результатом, который вы увидите при «инвертировании» логического массива:

 >>> pd.isnull([np.nan])
array([ True])
>>> ~pd.isnull([np.nan])
array([False])
  

Здесь есть несколько странных вещей. Обратите внимание, что:

 >>> pd.isnull(np.nan)
True
  

Итак, исключая numpy и pandas, вы, по сути, спрашиваете, почему:

 >>> ~True
-2
  

Это происходит потому bool , что является подклассом int :

 >>> issubclass(bool, int)
True
>>> True == 1
True
  

Выражение ~x подключается к type(x).__invert__ модели данных . Теперь bool не реализуется __invert__ , поэтому он возвращается к первому суперклассу, который это делает, т. е. int :

 >>> int.__invert__(True)
-2
  

Для дополнения two это, ~x по сути, вычисления -(x 1) . Документы фактически определяют это как таковое.

К сожалению, было бы нелегко bool переопределить __invert__ более разумным способом, т. Е. ~b Вернуть тот же результат, not b что и, сохраняя при этом гарантию обратной совместимости, что bools являются целыми числами. В итоге вы получите тревожный особый случай, когда x == y , но ~x != ~y .

Комментарии:

1. Ах, теперь это имеет смысл, спасибо. Объединение вашего ответа с ответом @CiaPan объединяет все это в том, как писать лучшие тесты.

Ответ №2:

Это потому, что вы использовали арифметический оператор отрицания bitwie вместо логического отрицания.