numpy数组与nan到标量的不等式比较

时间:2014-08-17 02:35:11

标签: python numpy indexing nan inequality

我正在尝试将低于阈值的数组成员设置为nan。这是质量保证/质量控制过程的一部分,输入的数据可能已经有插槽纳米。

所以作为一个例子,我的阈值可能是-1000,因此我想在以下数组中将-3000设置为nan

x = np.array([np.nan,1.,2.,-3000.,np.nan,5.])

以下内容:

x[x < -1000.] = np.nan

产生正确的行为,但也产生RuntimeWarning,但是禁用警告的开销

warnings.filterwarnings("ignore")
...
warnints.resetwarnings()

有点沉重,可能有点不安全。

尝试使用花式索引进行两次索引,如下所示不会产生任何影响:

nonan = np.where(~np.isnan(x))[0]
x[nonan][x[nonan] < -1000.] = np.nan

我认为这是因为由于整数索引或使用索引两次而产生副本。

有没有人有一个相对简单的解决方案?在这个过程中使用蒙面数组会很好,但最终的产品必须是一个ndarray,我不能引入新的依赖。感谢。

5 个答案:

答案 0 :(得分:12)

一种选择是使用numpy.errstate禁用相关警告:

with numpy.errstate(invalid='ignore'):
    ...

要全局关闭相关警告,请使用numpy.seterr

答案 1 :(得分:9)

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

答案 2 :(得分:1)

我个人忽略了已经给出的答案中使用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 ufunc接受可选参数where,并且仅将其计算为真,不像np.where函数评估两个选项然后选择相关参数。然后使用out参数设置所需的输出。

答案 3 :(得分:1)

有点晚了,但这就是我的做法:

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

答案 4 :(得分:1)

np.less()有一个where参数,用于控制将在何处应用操作。因此,您可以这样做:

x[np.less(x, -1000., where=~np.isnan(x))] = np.nan