为什么在numpy.nan的情况下`max`和`min`表现得如此奇怪?

3
我偶然发现了一些关于maxminnumpy.nan的奇怪行为,我很好奇这些行为背后的原因。

考虑在python3中运行以下代码:

import numpy as np

max(np.nan, 0)     # outputs nan 
max(np.nan, 10000) # outputs nan
max(0, np.nan)     # outputs 0
max(10000, np.nan) # outputs 10000

我尝试了很多不同的数值,发现第一个给定的数值总是被返回。同样的行为也可以在min函数中观察到。我原以为输出应该一直是nan,甚至会抛出错误,但结果却让人意外。 Math.nan也有相同的行为。

我非常好奇这种行为的原因 - 有人有什么想法吗?


@sascha 他正在调用标准的 Python minmax,而且他的参数对于这个函数是有意义的。 - abarnert
这里没有任何特定于numpy的内容。您可以使用math.nandecimal.Decimal('nan')或任何遵循NaN定义语义的内容,都会得到相同的行为。 (好吧,Decimalnumpy允许您配置IEEE样式标志以进行NaN行为,并且默认情况下使用信号NaN,因此您可以使其从decimal引发,例如InvalidOperation。)您甚至可以创建一个完全不同的类型,其语义与NaN不同,除非它们定义了“安静”的部分排序并出现类似的怪异行为。 - abarnert
2个回答

8

编写自己的max函数。请记住,NaN将导致任何大于、等于或小于比较返回False。例如,

def my_max(iter):
    result = iter[0]
    for val in iter[1:]:
        if result < val:
            result = val
    return result

如果你从一个数字开始比较,那么比较会失败,这个数字就成为了结果。如果你从nan开始,任何比较都会失败,结果将一直停留在初始的nan值。

并不总是第一个值,只是按照上述机制得到的结果。例如:

>>> nan = numpy.nan
>>> max([7, nan, 15, nan, 5])
15
>>> max([nan, 7, nan, 15, nan, 5])
nan

2

max 不知道浮点数或 NaN(不是数字)的任何信息。它假定实际上存在参数之间的排序关系,而当不存在这样的关系时,它可能会产生荒谬的结果,如 NaN 的情况。

numpy.maximum 表现得更合理:

>>> numpy.maximum(numpy.nan, 1)
nan
>>> numpy.maximum(1, numpy.nan)
nan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接