用python中的默认值替换高于和低于阈值的列表值?

Posted

技术标签:

【中文标题】用python中的默认值替换高于和低于阈值的列表值?【英文标题】:Replace list values above and below thresholds with default value in python? 【发布时间】:2017-01-14 19:23:05 【问题描述】:

我正在尝试用默认值替换低于和高于阈值的“坏值”(例如,将它们设置为 NaN)。 我正在取消一个具有 1000k 值及更多值的 numpy 数组 - 所以性能是一个问题。

我的原型分两步完成操作,是否可以一步完成?

import numpy as np

data = np.array([0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])

upper_threshold = 7
lower_threshold = 1
default_value = np.NaN

# is it possible to do this in one expression?
data[data > upper_threshold] = default_value
data[data < lower_threshold] = default_value

print data # [ nan   1.   2.   3.   4.   5.   6.   7.  nan  nan]

正如在此相关问题中所评论的 (Pythonic way to replace list values with upper and lower bound (clamping, clipping, thresholding)?)

与许多其他函数一样,np.clip 是 python,但它遵循 arr.clip 方法。对于常规数组,该方法被编译,因此会更快(大约 2 倍)。 – hpaulj

我也希望能找到更快的方法,提前谢谢!

【问题讨论】:

【参考方案1】:

boolean-indexing 与组合掩码一起使用-

data[(data > upper_threshold) | (data < lower_threshold)] = default_value

运行时测试-

In [109]: def onepass(data, upper_threshold, lower_threshold, default_value):
     ...:     mask = (data > upper_threshold) | (data < lower_threshold)
     ...:     data[mask] = default_value
     ...: 
     ...: def twopass(data, upper_threshold, lower_threshold, default_value):
     ...:     data[data > upper_threshold] = default_value
     ...:     data[data < lower_threshold] = default_value
     ...:     

In [110]: upper_threshold = 7
     ...: lower_threshold = 1
     ...: default_value = np.NaN
     ...: 

In [111]: data = np.random.randint(-4,11,(1000000)).astype(float)

In [112]: %timeit twopass(data, upper_threshold, lower_threshold, default_value)
100 loops, best of 3: 2.41 ms per loop

In [113]: data = np.random.randint(-4,11,(1000000)).astype(float)

In [114]: %timeit onepass(data, upper_threshold, lower_threshold, default_value)
100 loops, best of 3: 2.74 ms per loop

使用建议的one-pass-indexing 方法,我们的表现似乎并没有更好。原因可能是 OR-ing 掩码的计算比直接使用布尔索引本身分配值要昂贵一些。

【讨论】:

啊,很好,我尝试了data[upper_threshold &gt; data &gt; upper_threshold)] = default_value,它引发了一个错误。这是添加多个条件的方法 - 非常感谢。 &gt;...&gt; 仅适用于标量 Python 表达式。 numpy 需要显式的 or/and() 也很重要。

以上是关于用python中的默认值替换高于和低于阈值的列表值?的主要内容,如果未能解决你的问题,请参考以下文章

PySpark 将低于计数阈值的值替换为值

Python时间序列 - 计算低于/高于和指定最短持续时间阈值的周期

利用 opencv实现图像自适应二值化 --python

华为云技术分享灰度图二值化算法

根据阈值OpenCV C++改变像素的RGB值

python - 用两个不同列表中的值替换列表的布尔值[重复]