我有一个带NaN的数组,比如说
>>> a = np.random.randn(3, 3)
>>> a[1, 1] = a[2, 2] = np.nan
>>> a
array([[-1.68425874, 0.65435007, 0.55068277],
[ 0.71726307, nan, -0.09614409],
[-1.45679335, -0.12772348, nan]])
我想将此数组中的负数设置为-1
。这样做“直截了当”会导致警告,我试图避免:
>>> a[a < 0] = -1
__main__:1: RuntimeWarning: invalid value encountered in less
>>> a
array([[-1. , 0.65435007, 0.55068277],
[ 0.71726307, nan, -1. ],
[-1. , -1. , nan]])
对掩码应用AND会产生相同的警告,因为当然a < 0
被计算为一个单独的临时数组:
>>> n = ~np.isnan(a)
>>> a[n & (a < 0)] = -1
__main__:1: RuntimeWarning: invalid value encountered in less
当我尝试在a
之外应用掩码时,掩码部分不会写回原始数组:
>>> n = ~np.isnan(a)
>>> a[n][a[n] < 0] = -1
>>> a
array([[-1.68425874, 0.65435007, 0.55068277],
[ 0.71726307, nan, -0.09614409],
[-1.45679335, -0.12772348, nan]])
我能解决这个问题的唯一方法是使用免费的a
中间掩码版本:
>>> n = ~np.isnan(a)
>>> b = a[n]
>>> b[b < 0] = -1
>>> a[n] = b
>>> a
array([[-1. , 0.65435007, 0.55068277],
[ 0.71726307, nan, -1. ],
[-1. , -1. , nan]])
是否有更简单的方法在存在NaN的情况下执行此屏蔽分配?如果可能的话,我想在不使用掩码数组的情况下解决这个问题。
注意
上面的代码段最好用
运行import numpy as np
import warnings
np.seterr(all='warn')
warnings.simplefilter("always")
答案 0 :(得分:2)
如果您想避免在包含a < 0
的{{1}}的{{1}}发生此警告,我认为使用a
或NaNs
索引会有其他方法flattened
个职位然后进行比较。因此,我们将采用两种方法来实现这一理念。
具有扁平指数的一个 -
row-column
另一个下标索引 -
non-Nan
答案 1 :(得分:2)
您可以暂时取消警告,这是您所追求的吗?
In [9]: a = np.random.randn(3, 3)
In [10]: a[1, 1] = a[2, 2] = np.nan
In [11]: with np.errstate(invalid='ignore'):
....: a[a < 0] = -1
....:
答案 2 :(得分:1)
找到我发现的np.nan...
np.nan_to_num
个函数
In [569]: a=np.arange(9.).reshape(3,3)-5
In [570]: a[[1,2],[1,2]]=np.nan
In [571]: a
Out[571]:
array([[ -5., -4., -3.],
[ -2., nan, 0.],
[ 1., 2., nan]])
In [572]: np.nan_to_num(a) # replace nan with 0
Out[572]:
array([[-5., -4., -3.],
[-2., 0., 0.],
[ 1., 2., 0.]])
In [573]: np.nan_to_num(a)<0 # and safely do the <
Out[573]:
array([[ True, True, True],
[ True, False, False],
[False, False, False]], dtype=bool)
In [574]: a[np.nan_to_num(a)<0]=-1
In [575]: a
Out[575]:
array([[ -1., -1., -1.],
[ -1., nan, 0.],
[ 1., 2., nan]])
查看nan_to_num
代码,看起来它使用了屏蔽的copyto
:
In [577]: a1=a.copy(); np.copyto(a1, 0.0, where=np.isnan(a1))
In [578]: a1
Out[578]:
array([[-1., -1., -1.],
[-1., 0., 0.],
[ 1., 2., 0.]])
所以它就像你的版本中的“无偿”版本一样。掩码,但它隐藏在函数中。
np.place
,np.putmask
是使用掩码的其他函数。