numpy数组与标量的nan不等比较
warnings.filterwarnings("ignore")
...
warnints.resetwarnings()
我想把一个数组中低于某个阈值的元素设置为nan。这是质量检查过程的一部分,因为输入的数据可能已经有一些位置是nan。
举个例子,我的阈值可能是-1000,所以我想把数组中的-3000设置为nan。
x = np.array([np.nan,1.,2.,-3000.,np.nan,5.])
下面这段代码:
x[x < -1000.] = np.nan
能正确运行,但会产生一个运行时警告,而关闭这个警告的开销有点大,而且可能不太安全。
尝试用复杂的索引方式两次索引,如下所示,并没有产生任何效果:
nonan = np.where(~np.isnan(x))[0]
x[nonan][x[nonan] < -1000.] = np.nan
我猜这是因为使用整数索引或两次索引时会生成一个副本。
有没有人能提供一个相对简单的解决方案?使用掩码数组也可以,但最终的结果必须是ndarray,并且我不能引入新的依赖。谢谢。
5 个回答
2
虽然有点晚了,但我会这样做:
x = np.array([np.nan,1.,2.,-3000.,np.nan,5.])
igood=np.where(~np.isnan(x))[0]
x[igood[x[igood]<-1000.]]=np.nan
2
我个人在使用之前提到的np.errstate上下文管理器时,会忽略警告,因为代码的清晰度比花额外时间更重要,但这里有一个替代方案。
# given
x = np.array([np.nan, 1., 2., -3000., np.nan, 5.])
# apply NaNs as desired
mask = np.zeros(x.shape, dtype=bool)
np.less(x, -1000, out=mask, where=~np.isnan(x))
x[mask] = np.nan
# expected output and comparison
y = np.array([np.nan, 1., 2., np.nan, np.nan, 5.])
assert np.allclose(x, y, rtol=0., atol=1e-14, equal_nan=True)
numpy中的less
这个函数有一个可选的参数where
,它只在条件为真的时候进行计算,这和np.where
函数不同,后者会计算两个选项,然后选择一个相关的结果。你可以通过out
参数来设置在条件不成立时的期望输出。
9
np.less() 这个函数有一个叫做 where
的参数,它可以控制这个操作将在哪些地方进行。所以你可以这样做:
x[np.less(x, -1000., where=~np.isnan(x))] = np.nan
18
一种选择是使用 numpy.errstate
来关闭相关的警告:
with numpy.errstate(invalid='ignore'):
...
如果你想全局关闭这些警告,可以使用 numpy.seterr
。
17
任何将NaN(不是一个数字)与非NaN值进行比较(除了!=
)的操作,结果总是会返回False,也就是说它们永远不会相等:
>>> x < -1000
array([False, False, False, True, False, False], dtype=bool)
所以你可以简单地忽略数组中已经存在的NaN,直接这样做:
>>> x[x < -1000] = np.nan
>>> x
array([ nan, 1., 2., nan, nan, 5.])
编辑 我在运行上面的代码时没有看到任何警告,但如果你真的想避免NaN,可以尝试这样做:
mask = ~np.isnan(x)
mask[mask] &= x[mask] < -1000
x[mask] = np.nan