numpy中“less_equal”中遇到“无效值”的原因可能是什么

时间:2016-01-22 20:14:05

标签: python arrays numpy runtime

我遇到过RuntimeWarning

 RuntimeWarning: invalid value encountered in less_equal

由我的这行代码生成:

center_dists[j] <= center_dists[i]

center_dists[j]center_dists[i]都是numpy数组

这个警告可能是什么原因?

5 个答案:

答案 0 :(得分:26)

最有可能发生这种情况,因为所涉及的输入中有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)

请注意输出中的第三列,该列对应于np.nan中涉及第三个元素B的比较,并且会产生所有False值。

答案 1 :(得分:4)

作为Divakar的回答和他对如何抑制RuntimeWarning的评论的后续措施,一种更安全的方法是使用with np.errstate()仅在本地抑制({{3 }}:通常最好在与np.nan的比较产生False时发出警告,并且仅在确实是预期的时候才忽略警告。以下是OP的示例:

with np.errstate(invalid='ignore'):
  center_dists[j] <= center_dists[i]

退出with块后,错误处理将重置为以前的状态。

也可以通过传递invalid value encountered而不是all='ignore'来忽略所有错误。有趣的是,kwargs的文档中的np.errstate()缺少了,但是docs的文档中没有。 (似乎是np.errstate()文档中的一个小错误。)

答案 2 :(得分:0)

发生这种情况的原因是数据框中的Nan个值,而使用DF完全可以。

在Pycharm中,这对我来说就像是一种魅力:

import warnings

warnings.simplefilter(action = "ignore", category = RuntimeWarning)

答案 3 :(得分:0)

Numpy dtypes非常严格。因此它不会产生像np.array([False, True, np.nan])这样的数组,它会返回array([ 0., 1., nan])这是一个float数组。

如果您尝试更改布尔数组,例如:

x= np.array([False, False, False])
x[0] = 5

将重新运行array([ True, False, False]) ...哇

但是我认为5>np.nan不能为False,它应该为nanFalse意味着已经进行了数据比较,并且返回了类似{{ 1}},我认为这是一场灾难。 Numpy生成我们实际上没有的数据。如果它可以返回3>5,那么我们可以轻松地处理它。

所以我试图用一个函数来修改行为。

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)

但是我认为整个内存结构都以这种方式改变了。它不会产生具有统一单位的内存块,而是会生成一个指针块,其中实际数据位于其他位置。因此,函数的执行速度可能会变慢,这可能就是Numpy不这样做的原因。我们需要一个array([nan, False, True, True, True, True, nan, nan, nan], dtype=object) dtype,它也将包含superBool,或者我们只需要使用浮点数组np.nan

答案 4 :(得分:0)

添加到上述答案中的另一种抑制此警告的方法是to use numpy.less explicitly,提供whereout参数:

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)。