4

If numpy.any() returns True the comparison with is True fails but with == True works. Does anyone know why?

A minimal example

from __future__ import print_function
import numpy

a = numpy.array([True])

if a.any() == True:
  print('== works')

if a.any() is True:
  print('is works')

The output of this code is just == works.

floren
  • 51
  • 4
  • Why are you using `is` for this comparison anyway? [In this context `==` is the semantically correct comparison](https://stackoverflow.com/questions/132988/is-there-a-difference-between-and-is-in-python) – Cory Kramer Sep 01 '17 at 14:33
  • For the same reason `1 == 1.0` is `True` and `1 is 1.0` is `False`. 1 is an integer, 1.0 is a float. Two things can be equivalent while having different underlying structure. – Daniel F Sep 01 '17 at 19:47

4 Answers4

7

numpy has it's own booleans, numpy.True_ and numpy.False_ that have different identities from Python's native booleans. Anyway, you should be using == for such equity comparisons

>>> a.any() is True
False
>>> a.any() is numpy.True_
True
>>> True is numpy.True_
False
>>> True == numpy.True_
True
Chris_Rands
  • 38,994
  • 14
  • 83
  • 119
  • 3
    Actually, don’t check for boolean equality at all. Just do `if a.any()` or `if not a.any()`. – poke Sep 01 '17 at 14:38
  • @poke timgeb Yes agreed of course, in this specific boolean context, I meant in general that equity checks are preferable to identity ones (unless you're actually trying to check the identity of course) – Chris_Rands Sep 01 '17 at 14:41
3

The types of the returns are different:

>>> type(a.any())
<type 'numpy.bool_'>
>>> type(True)
<type 'bool'>

So, a.any() isn't True as such, it's only equal to True.

Seabass
  • 372
  • 1
  • 6
3

That's because a.any() does not return the standard Python True (an instance of the class bool).

>>> type(a.any())
<type 'numpy.bool_'>

So in short, numpy has its own True-value, but when you print it, it looks just like Python's built in True.

timgeb
  • 76,762
  • 20
  • 123
  • 145
1

numpy.any returns a numpy.bool_ which is a different datatype used by numpy.

So you cannot compare a numpy.bool_ with a Python bool using an identity check. You would have to use numpy’s true then: numpy.True_

>>> a.any() is numpy.True_
True

The main reason why they aren’t using Python’s bool is because numpy.bool_ is just a single byte whereas a Python bool is based on the Python int which will always be more expensive.

poke
  • 369,085
  • 72
  • 557
  • 602