Python 3.x 如何摆脱;RuntimeWarning:在“较大”中遇到无效值;
这个问题与许多与警告相关的问题非常相似Python 3.x 如何摆脱;RuntimeWarning:在“较大”中遇到无效值;,python-3.x,numpy,Python 3.x,Numpy,这个问题与许多与警告相关的问题非常相似RuntimeWarning:agreer/less/etc中遇到的值无效 然而,我找不到解决我的问题的方法,我认为应该有一个 因此,我有一个类似于这个的numpy.ndarray: array([[ nan, 1., nan, ..., nan, nan, nan], [ nan, nan, nan, ..., nan, nan, nan], [ nan, nan, nan, ..., nan, n
RuntimeWarning:agreer/less/etc中遇到的值无效
然而,我找不到解决我的问题的方法,我认为应该有一个
因此,我有一个类似于这个的numpy.ndarray
:
array([[ nan, 1., nan, ..., nan, nan, nan],
[ nan, nan, nan, ..., nan, nan, nan],
[ nan, nan, nan, ..., nan, nan, nan],
...,
[ nan, nan, nan, ..., nan, nan, nan],
[ nan, nan, nan, ..., nan, nan, nan],
[ nan, nan, nan, ..., nan, nan, nan]])
我想计算array>0.5
,这正好给出了我想要的结果,但带有与nan
进行比较的警告:
__main__:1: RuntimeWarning: invalid value encountered in greater
Out[68]:
array([[False, True, False, ..., False, False, False],
[False, False, False, ..., False, False, False],
[False, False, False, ..., False, False, False],
...,
[False, False, False, ..., False, False, False],
[False, False, False, ..., False, False, False],
[False, False, False, ..., False, False, False]], dtype=bool)
我基本上想计算array>0.5
,但没有显示警告
我的限制:
- 我不想用np.errstate(invalid='ignore'):
我需要维护原始数组,因此无法更改它
我提出了一个简单的解决方案:
- 更改原始矩阵中的
nan
(array[np.isnan(array)]=-np.inf
),在我进行比较后将其恢复回来(array[array=-np.inf]=np.nan
)
但我认为这只是在浪费时间,所有这些计算,而(我认为)它应该存在一种直接的方法来立即进行。我一直在探索numpy.ma
模块和numpy.where
函数,但我找不到我想要的“直接”解决方案
对此有何想法?每当比较至少包含一个NaN的数组时,您都会收到该警告。解决方案是使用掩蔽
仅比较非NaN元素,我们将尝试使用一个通用解决方案,在的帮助下覆盖所有类型的比较,如下所示-
def compare_nan_array(func, a, thresh):
out = ~np.isnan(a)
out[out] = func(a[out] , thresh)
return out
其想法是:
- 获得非南的面具
- 使用它从输入数组中获取非NaN值。然后执行所需的比较(大于、大于等于等)以获得另一个掩码,该掩码表示已屏蔽位置的已比较掩码输出
- 使用此选项优化非NAN的掩码,这是最终输出
样本运行-
In [41]: np.random.seed(0)
In [42]: a = np.random.randint(0,9,(4,5)).astype(float)
In [43]: a.ravel()[np.random.choice(a.size, 16, replace=0)] = np.nan
In [44]: a
Out[44]:
array([[ nan, nan, nan, nan, nan],
[ nan, nan, nan, 4., 7.],
[ nan, nan, nan, 1., nan],
[ nan, 7., nan, nan, nan]])
In [45]: a > 5 # Shows warning with the usual comparison
__main__:1: RuntimeWarning: invalid value encountered in greater
Out[45]:
array([[False, False, False, False, False],
[False, False, False, False, True],
[False, False, False, False, False],
[False, True, False, False, False]], dtype=bool)
# With suggested masking based method
In [46]: compare_nan_array(np.greater, a, 5)
Out[46]:
array([[False, False, False, False, False],
[False, False, False, False, True],
[False, False, False, False, False],
[False, True, False, False, False]], dtype=bool)
让我们测试小于5的泛型行为-
In [47]: a < 5
__main__:1: RuntimeWarning: invalid value encountered in less
Out[47]:
array([[False, False, False, False, False],
[False, False, False, True, False],
[False, False, False, True, False],
[False, False, False, False, False]], dtype=bool)
In [48]: compare_nan_array(np.less, a, 5)
Out[48]:
array([[False, False, False, False, False],
[False, False, False, True, False],
[False, False, False, True, False],
[False, False, False, False, False]], dtype=bool)
[47]中的:a<5
__main\uuu1:运行时警告:在less中遇到无效值
出[47]:
数组([[False,False,False,False,False],
[假,假,假,真,假],
[假,假,假,真,假],
[False,False,False,False,False]],dtype=bool)
[48]中:比较数组(np.less,a,5)
出[48]:
数组([[False,False,False,False,False],
[假,假,假,真,假],
[假,假,假,真,假],
[False,False,False,False,False]],dtype=bool)
有一个更好的方法-您不想永远隐藏警告,因为它可以帮助您以后发现其他错误
以下是本问题中的建议:
正确的方法:
如果结果是您想要的,您可以只写:
with np.errstate(invalid='ignore'):
result = (array > 0.5)
# ... use result, and your warnings are not suppressed.
另一种错误的方式:
否则,您可以通过复制阵列来满足您的限制:
to_compare = array.copy()
to_compare[np.isnan(to_compare)] = 0.5 # you don't need -np.inf, anything <= 0.5 is OK
result = (to_compare > 0.5)
to_compare=array.copy()
to_compare[np.isnan(to_compare)]=0.5#您不需要-np.inf,任何0.5)
您不需要“恢复”阵列中的nan。使用比较函数(value!=nan)和(value>0.5)@Alexvonbrandfels您的解决方案不起作用。首先,我必须将nan
更改为numpy.nan
。但是,即使在这之后,我仍然有一个错误:ValueError:包含多个元素的数组的真值是不明确的。使用a.any()或a.all()
“我不想只抑制警告”-为什么不?@user2357112,因为我认为这不正确。我在一个三值逻辑中进行比较,因此,将NaN与其他值进行比较的结果可能是错误的或其他值。在未来版本的numpy中,这个结果可能会改变,因此我想确保我总是会有一个预期的结果“在未来版本的numpy中,这个结果可能会改变”-这是极不可能发生的,如果发生了,你将不得不重新考虑你所有的NaN处理。该死!解决办法其实很简单。我一直在关注你所有的编辑eh非常感谢你,这正是我想要的!但是可读性降低了。设置为默认方式怎么样?这不是我所说的“消除警告”。它小心地避免引起这种警告的操作。它在代码和运行时都有开销。但是,除了黑客攻击NumPy的源代码之外,您实际上还可以执行np。seterr(invalid='ignore')
@TomaszGandor OP已经尝试过了,不想这样做。它在问题的My restrictions:
部分下。当您试图从具有nan
值的数组中获取符号时,解决方案也可以应用于np.sign()
。错误将是运行时警告:符号中遇到无效值。您可以使用dfS['b']=evaluate\u nan\u数组(np.sign,df['a'])而不是df['b']=np.sign(df['a'])
其中def evaluate\u nan\u数组(func,a):out=~np.isnan(a)out[out]=func(a[out])返回