简体   繁体   中英

numpy.nan weird behaviour in hashed object

I am experiencing a weird behaviour when using numpy.nan that I can't understand. Here is a minimal example:

from numpy import nan

def _bool3key(x):
  """
  Defines the keys used to order the list.
  The only allowed values are True, False, 1,0 and numpy.nan.
  """ 
  return _bool3key.__logic_sort__[x]
_bool3key.__logic_sort__ = {0:-1, nan:0 , 1:1}

def and3(*args):
   return min(*args,key=_bool3key)


def f(x):
  """long function that produces in output a vector containing only 0, nan and 1s.
  pass #

Sometimes the and3 function fails, despite in the vector returned by f(x) there are only 0, nan, or 1 values: the reason is that nan is not of type numpy.nan...

For example v = f(x) produced a vector [nan,nan] . However if I try to type: v[0] is nan I get False (which is what causes and3 not to work); the weird thing though is that v[1] is nan is True .

What is causing this behaviour? How can I correctly use a nan value in my and3 function??

nan should not be used as an index for a dict because it does not successfully compare with itself.

>>> float('nan') == float('nan')
False
>>> numpy.nan == numpy.nan
False

However, nan can be detected using math.isnan() :

>>> math.isnan(numpy.nan)
True

If you use

_bool3key.__logic_sort__ = {0:-1, nan:0 , 1:1}

then one problem you might run into is that float('nan') is not recognized as the same key as np.nan :

In [17]: _bool3key(float('nan'))
KeyError: nan

Here is a workaround:

def _bool3key(x, logic_sort={0: -1, 1: 1}):
    """
    Defines the keys used to order the list.
    The only allowed values are True, False, 1,0 and nan.
    """
    return 0 if np.isnan(x) else logic_sort[x]

Also, attribute lookups are slower than local variable lookups, so you'll get slightly better performance defining logic_sort as a default parameter than by making it a function attribute. You don't have to define it outside of the function, and it is a little easier to read too.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM