Python 为什么';t numpy.unique是否识别多个numpy.nan值相同?

Python 为什么';t numpy.unique是否识别多个numpy.nan值相同?,python,numpy,Python,Numpy,我有一个简短的脚本示例: 将numpy导入为np 打印('numpy version:',np.version.version) foo=np.full(10,5) 条形=np.满(10,np.nan) 打印('foo:',foo) 打印('foo的唯一值:',np.Unique(foo)) 打印('条:',条) 打印('条的唯一值:',np.唯一(条)) 它将打印以下结果: numpy version: 1.16.4 foo: [5 5 5 5

我有一个简短的脚本示例:

将numpy导入为np
打印('numpy version:',np.version.version)
foo=np.full(10,5)
条形=np.满(10,np.nan)
打印('foo:',foo)
打印('foo的唯一值:',np.Unique(foo))
打印('条:',条)
打印('条的唯一值:',np.唯一(条))
它将打印以下结果:

numpy version:        1.16.4
foo:                  [5 5 5 5 5 5 5 5 5 5]
Unique values of foo: [5]
bar:                  [nan nan nan nan nan nan nan nan nan nan]
Unique values of bar: [nan nan nan nan nan nan nan nan nan nan]
我的问题:

  • 为什么
    np.unique()
    在接收到
    bar
    作为输入时不只返回一个
    nan
    值?这肯定是个错误,对吗?或者,如果这是正确的,预期的行为,那么为什么它是正确的
  • 对于获得
    foo
    所示的更典型的行为,推荐的解决方法(如果有)是什么

  • 第一个问题:

    如你所见:

    >>> np.nan == np.nan
    False
    >>>
    
    np.nan
    s不相等

    第二个问题:

    这不可能很美,我唯一能想到的是:

    >>> a = np.unique(np.where(np.isnan(bar), 0, bar))
    >>> np.where(a == 0, np.nan, a)
    array([ nan])
    >>> 
    

    为了回答您的问题,请回答为什么:IEEE规范()针对浮点数,这就是为什么numpy不等于任何东西,包括它本身。Numpy尊重这一点,这就是为什么
    np.nan==np.nan
    为false

    人们对此表示不满,但这是一个很难做出的选择,因为NaN可能来自不平等的事物。例如,这个表达式应该是真的吗

    np.sqrt(-1) == np.sqrt(-2) 
    

    两人都对NaN进行了评估,但说上述内容应该是真实的似乎是非常错误的。您需要决定如何在代码中处理NaN,如果您想以相同的方式处理NaN,您当然可以。

    我不确定是否可以完全推荐它,但如果唯一元素的排序顺序无关紧要:

    # make example with nans                                                                                                    
    x = np.arange(15)%5-2                                                                                       
    y = x.astype(bool)/x                                                       
    y                                                                                                           
    # array([-0.5, -1. ,  nan,  1. ,  0.5, -0.5, -1. ,  nan,  1. ,  0.5, -0.5,                                        
    #        -1. ,  nan,  1. ,  0.5])
    
    # trick comes here                                                                                 
    np.unique(y.view(int)).view(float)
    # array([-0.5, -1. ,  nan,  0.5,  1. ])                                                                           
    
    但是,请注意,int和float之间的映射不是100%一对一,例如:

    (np.array(np.nan).view(int)+1).view(float)
    # nan                                                                                                             
    

    最后一个nan与标准nan相比并不相等,即使我们将强制转换应用于int和back技巧。

    我喜欢你的解决方法,当然,如果
    bar
    除了
    nan
    s之外还包含任何
    0
    值,它似乎会得到稍微不正确的结果。但至少它可以在大多数情况下工作。@stachyra Yeah
    NaN
    s不容易对付