np.isnan(1.0) is False 的结果是 False

作者: , 共 1127 字 , 共阅读 0

今天写 Python 代码时遇到一个恶心的 bug ,花了好一会才定位和搞清楚。我的目标是寻找第一个非 NAN 的数的位置(其中 array 是一个 numpy 向量),很自然有下面实现:

import numpy as np
index = next((i for i, x in enumerate(array) if np.isnan(x) is False), None)

结果发现总是返回 None ,也就是 array 数组里全是 NAN。但这是不可能的。最后在 Python 命令里试了一下,才发现 np.isnan(1.0) is False运行结果都是 False。

chatgpt 的解释很清楚。问:

np.isnan(1) is False 为什么结果是 False ,np.isnan(1)返回 False ,它 is False 应该是 True 呀。

chatgpt gpt-4 的回答是:

您的理解是正确的,np.isnan(1) 返回的结果确实是 False。在这里,您可能对 is 和 == 的使用有所混淆。

is 和 == 都用于比较两个对象,但它们之间存在一些关键区别:

  • is 用于比较两个对象是否相同,即它们是否引用内存中的同一个对象。
  • == 用于比较两个对象的值是否相等。
  • 在您的例子中,np.isnan(1) 返回的是一个 numpy.bool_ 类型的对象,其值为 False。而 Python 中的 False 是一个内置的 bool 类型对象。尽管 np.isnan(1) 返回的对象和内置的 False 都表示逻辑上的假,但它们在内存中是不同的对象。

因此,当您使用 is 进行比较时,结果为 False ,因为 np.isnan(1) 返回的对象和内置的 False 不是同一个对象。如果您想要比较它们的值是否相等,您应该使用 ==:

import numpy as np

result = np.isnan(1) == False
print(result)  # 输出 True

这里,np.isnan(1) == False 返回 True ,因为 np.isnan(1) 的值与 False 的值相等。

其实用==也不太好, PEP 8 格式检查会提示(但这感觉更像 pep8 的 bug ):

PEP8: E712 comparison to False should be 'if cond is False:' or 'if not cond:'

所以最佳方式应该是:

if not np.isnan(x):
    pass

Q. E. D.

类似文章:
编程 » Python, numpy
numpy 的一维向量:
编程 » pandas, numpy, Python, C++
首先任意定义一个结构,注意不要用 std::string 非平凡布局的变量,用 char[] 代替:
编程 » NaN, Python, Javascript, JSON
一般而言,在 Python 里:
相似度: 0.068
很多人一看到 NP-hard ,就从字面上理解成为比 NP 还难的问题。但如果这里的「更难」指得是解决问题所花费时间更长的话,这个论断是不正确的。从算法角度来看, NP-hard 问题的确比 NP 难,但比 NP 还难(指花费时间更多)的问题却不见得是 NP-hard 的。
编程 » Python
今天写一段程序时遇到一个问题,查了好一会才搞清楚。代码可以简化为下面这个小代码:
IT » openai, chatgpt, llm
chatgpt 的开发应用需要使用 API key。申请地址是:https://platform.openai.com/account/api-keys
Python的命令行包argparse内置了-h, --help命令。但它没有分组,和其它的命令混在一起,并且显示在最前面。我更喜欢把它放在单独的「LOG 和帮助」分组:
我们西沟林场露营的第二天,其他人都去爬八大楼子长城,而我们则决定不走重复路线,前往蟠龙山长城。这是我们第一次来到这个地方,但我们却惊喜地发现,这里也是野长城,并且有各种类型,城墙高大峻峭,砖墙残破不堪,墙体崩塌无处不在。这里是我唯一听说过的可合法攀爬野长城的景点,保留着原汁原味的野长城形态,据说甚至还有些墙壁被当年的抗日战争中机枪打穿的痕迹。
今天,我们从古北口保卫战纪念碑出发,经蟠龙山长城,穿越到金山岭长城。从金山岭长城的东门口出。总里程 14 公里,爬升约 760 米。轨迹已上传到两步路20230409 古北口~蟠龙山~金山岭穿越