#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 вместо логического отрицания.