为什么 NaN 值会使 min 和 max 对顺序敏感?

Why do NaN values make min and max sensitive to order?

> import numpy as np

> min(50, np.NaN)
50   
> min(np.NaN, 50)
nan

(与 max 发生相同的行为)

我知道我可以通过使用 numpy.nanmin 来避免这种行为。但是,当顺序颠倒时,是什么导致了变化呢? min 对输入顺序敏感吗?

是的 nan 破坏了正确的排序,因为它 总是 比较为 False。很多东西跟nan不一致:

In [2]: 3.0 < float('nan')
Out[2]: False

In [3]: float('nan') < 3.0
Out[3]: False

In [4]: float('nan') == 3.0
Out[4]: False

minmax 只能为您提供一致的结果,因为您使用的是定义明确的顺序,如果您可以使用 nan[=17=,则数字类型不是]

Is min sensitive to input order?

是的。

https://docs.python.org/3/library/functions.html#min

“如果多个项目是最小的,函数 return 是遇到的第一个。”

文档没有具体说明面对顺序不一致的项目时“最小”是如何定义的,但 min 很可能是基于循环元素并使用 < 运算符来确定如果新元素小于目前找到的最小项。

为了证实这个假设,我们可以阅读源代码(在 https://github.com/python/cpython/blob/c96d00e88ead8f99bb6aa1357928ac4545d9287c/Python/bltinmodule.c 中搜索 builtin_min 和 min_max),它有点令人困惑,因为 min 和 max 的实现是结合在一起的,变量名称似乎是基于它是一个 max 函数,但并不难理解。

它确实按顺序遍历元素并通过调用 PyObject_RichCompareBool 与 Py_LT 的“opid”进行比较,这是 C API 等效的python < 运算符。

NaN 和数字之间的比较 return false,因此在包含数字和 NaN 的列表中,如果第一个位置有 NaN,它将被视为最小值,因为没有数字会“小于”它.另一方面,如果 NaN 不在第一个位置,那么它将被有效地跳过,因为它不“小于”任何数字。