numpy 中 'invalid value encountered in less_equal' 的原因可能是什么
What might be the cause of 'invalid value encountered in less_equal' in numpy
我遇到了 RuntimeWarning
RuntimeWarning: invalid value encountered in less_equal
由我的这行代码生成:
center_dists[j] <= center_dists[i]
center_dists[j]
和center_dists[i]
都是numpy数组
出现此警告的原因可能是什么?
这很可能是因为所涉及的输入中某处存在 np.nan
。它的一个例子如下所示-
In [1]: A = np.array([4, 2, 1])
In [2]: B = np.array([2, 2, np.nan])
In [3]: A<=B
RuntimeWarning: invalid value encountered in less_equal
Out[3]: array([False, True, False], dtype=bool)
对于所有涉及 np.nan
的比较,它会输出 False
。让我们确认一下以进行 broadcasted
比较。这是一个示例 -
In [1]: A = np.array([4, 2, 1])
In [2]: B = np.array([2, 2, np.nan])
In [3]: A[:,None] <= B
RuntimeWarning: invalid value encountered in less_equal
Out[3]:
array([[False, False, False],
[ True, True, False],
[ True, True, False]], dtype=bool)
请注意输出中的第三列,它对应于涉及 B
中的第三个元素 np.nan
的比较,结果是所有 False
个值。
作为 Divakar 的回答及其关于如何抑制 RuntimeWarning
的评论的后续行动,更安全的方法是使用 [=12= 仅在 本地 抑制它们] (docs):当比较 np.nan
产生 False
时,通常会收到警告是很好的,只有当这确实是预期的时候才忽略警告。这里以 OP 为例:
with np.errstate(invalid='ignore'):
center_dists[j] <= center_dists[i]
退出 with
块后,错误处理将重置为之前的状态。
而不是 invalid value encountered
,也可以通过传递 all='ignore'
来忽略所有错误。有趣的是,np.errstate()
文档中的 kwargs
中没有,但 np.seterr()
文档中没有。 (似乎是 np.errstate()
文档中的一个小错误。)
这是由于数据帧中的 Nan
值造成的,这对于 DF 完全没问题。
在 Pycharm 中,这对我来说就像一个魅力:
import warnings
warnings.simplefilter(action = "ignore", category = RuntimeWarning)
Numpy 数据类型非常严格。所以它不会产生像 np.array([False, True, np.nan])
这样的数组,而是 returns array([ 0., 1., nan])
和 float
数组。
如果您尝试更改布尔数组,例如:
x= np.array([False, False, False])
x[0] = 5
将重新运行 array([ True, False, False])
...哇
但是我觉得5>np.nan
不可能是False
,应该是nan
,False
就说明做了数据比较,返回的结果是这样的3>5
,我认为这是一场灾难。 Numpy 产生我们实际上没有的数据。如果它可以返回 nan
那么我们就可以轻松处理它。
所以我尝试用函数修改行为。
def ngrater(x, y):
with np.errstate(invalid='ignore'):
c=x>y
c=c.astype(np.object)
c[np.isnan(x)] = np.nan
c[np.isnan(y)] = np.nan
return c
a = np.array([np.nan,1,2,3,4,5, np.nan, np.nan, np.nan]) #9 elements
b = np.array([0,1,-2,-3,-4,-5, -5, -5, -5]) #9 elements
ngrater(a,b)
returns:
array([nan, False, True, True, True, True, nan, nan, nan], dtype=object)
但我认为整个内存结构都以这种方式改变了。它不会获得具有统一单元的内存块,而是会生成一个指针块,其中真正的数据位于其他地方。所以功能可能会执行得更慢,这可能就是 Numpy 不这样做的原因。我们需要一个 superBool
dtype,它也将包含 np.nan
,或者我们只需要使用 float 数组 +1:True, -1:False, nan:nan
将上述答案添加到另一种抑制此警告的方法是 to use numpy.less
explicitly,提供 where
和 out
参数:
np.less([1, 2], [2, np.nan])
输出:array([ True, False])
导致运行时警告,
np.less([1, 2], [2, np.nan], where=np.isnan([2, np.nan])==False)
不计算第二个数组元素 according to the docs 的结果,留下未定义的值(我得到了两个元素的 True 输出),而
np.less([1, 2], [2, np.nan], where=np.isnan([2, np.nan])==False, out=np.full((1, 2), False)
将结果写入预先初始化为 False 的数组(因此总是在第二个元素中给出 False)。
我遇到了 RuntimeWarning
RuntimeWarning: invalid value encountered in less_equal
由我的这行代码生成:
center_dists[j] <= center_dists[i]
center_dists[j]
和center_dists[i]
都是numpy数组
出现此警告的原因可能是什么?
这很可能是因为所涉及的输入中某处存在 np.nan
。它的一个例子如下所示-
In [1]: A = np.array([4, 2, 1])
In [2]: B = np.array([2, 2, np.nan])
In [3]: A<=B
RuntimeWarning: invalid value encountered in less_equal
Out[3]: array([False, True, False], dtype=bool)
对于所有涉及 np.nan
的比较,它会输出 False
。让我们确认一下以进行 broadcasted
比较。这是一个示例 -
In [1]: A = np.array([4, 2, 1])
In [2]: B = np.array([2, 2, np.nan])
In [3]: A[:,None] <= B
RuntimeWarning: invalid value encountered in less_equal
Out[3]:
array([[False, False, False],
[ True, True, False],
[ True, True, False]], dtype=bool)
请注意输出中的第三列,它对应于涉及 B
中的第三个元素 np.nan
的比较,结果是所有 False
个值。
作为 Divakar 的回答及其关于如何抑制 RuntimeWarning
的评论的后续行动,更安全的方法是使用 [=12= 仅在 本地 抑制它们] (docs):当比较 np.nan
产生 False
时,通常会收到警告是很好的,只有当这确实是预期的时候才忽略警告。这里以 OP 为例:
with np.errstate(invalid='ignore'):
center_dists[j] <= center_dists[i]
退出 with
块后,错误处理将重置为之前的状态。
而不是 invalid value encountered
,也可以通过传递 all='ignore'
来忽略所有错误。有趣的是,np.errstate()
文档中的 kwargs
中没有,但 np.seterr()
文档中没有。 (似乎是 np.errstate()
文档中的一个小错误。)
这是由于数据帧中的 Nan
值造成的,这对于 DF 完全没问题。
在 Pycharm 中,这对我来说就像一个魅力:
import warnings
warnings.simplefilter(action = "ignore", category = RuntimeWarning)
Numpy 数据类型非常严格。所以它不会产生像 np.array([False, True, np.nan])
这样的数组,而是 returns array([ 0., 1., nan])
和 float
数组。
如果您尝试更改布尔数组,例如:
x= np.array([False, False, False])
x[0] = 5
将重新运行 array([ True, False, False])
...哇
但是我觉得5>np.nan
不可能是False
,应该是nan
,False
就说明做了数据比较,返回的结果是这样的3>5
,我认为这是一场灾难。 Numpy 产生我们实际上没有的数据。如果它可以返回 nan
那么我们就可以轻松处理它。
所以我尝试用函数修改行为。
def ngrater(x, y):
with np.errstate(invalid='ignore'):
c=x>y
c=c.astype(np.object)
c[np.isnan(x)] = np.nan
c[np.isnan(y)] = np.nan
return c
a = np.array([np.nan,1,2,3,4,5, np.nan, np.nan, np.nan]) #9 elements
b = np.array([0,1,-2,-3,-4,-5, -5, -5, -5]) #9 elements
ngrater(a,b)
returns:
array([nan, False, True, True, True, True, nan, nan, nan], dtype=object)
但我认为整个内存结构都以这种方式改变了。它不会获得具有统一单元的内存块,而是会生成一个指针块,其中真正的数据位于其他地方。所以功能可能会执行得更慢,这可能就是 Numpy 不这样做的原因。我们需要一个 superBool
dtype,它也将包含 np.nan
,或者我们只需要使用 float 数组 +1:True, -1:False, nan:nan
将上述答案添加到另一种抑制此警告的方法是 to use numpy.less
explicitly,提供 where
和 out
参数:
np.less([1, 2], [2, np.nan])
输出:array([ True, False])
导致运行时警告,
np.less([1, 2], [2, np.nan], where=np.isnan([2, np.nan])==False)
不计算第二个数组元素 according to the docs 的结果,留下未定义的值(我得到了两个元素的 True 输出),而
np.less([1, 2], [2, np.nan], where=np.isnan([2, np.nan])==False, out=np.full((1, 2), False)
将结果写入预先初始化为 False 的数组(因此总是在第二个元素中给出 False)。