我有以下数组
array = np.array([-0.5, -2, -1, -0.5, -0.25, 0, 0, -2, -1, 0.25, 0.5, 1, 2])
并希望应用两个阈值,以便将-1.0
以下的所有值设置为1
,将 -0.3
以上的所有值设置为{{ 1}}。对于中间值,应遵循以下规则:如果最后一个值低于0
,那么它应该是-1.0
但如果最后一个值高于1
,那么它应该是-0.3
。
对于上面的示例数组,输出应为
0
如果多个连续值介于target = np.array([0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0])
和-1.0
之间,那么它应该尽可能地返回,直到有一个高于或低于这两个阈值的值并相应地设置输出。
我试图通过迭代数组并在for循环中使用-0.3
来找到下一个出现的值,但是它不能正常工作:
while
如何将两个阈值应用于我的阵列?如上所述?
答案 0 :(得分:1)
您要实现的目标是"带滞后的阈值"。为此,我调整了this answer中非常好的算法:
鉴于您的测试数据,
import numpy as np
array = np.array([-0.5, -2, -1, -0.5, -0.25, 0, 0, -2, -1, 0.25, 0.5, 1, 2])
您检测到哪些值低于第一个阈值-1.0
,哪些值高于第二个阈值-0.3
:
low_values = array <= -1.0
high_values = array >= -0.3
这些是您了解结果的值:1
或0
。对于所有其他值,它取决于其邻居。因此,low_values
或high_values
为True
的所有值都是已知的。
您可以使用以下命令获取所有已知元素的索引:
known_values = high_values | low_values
known_idx = np.nonzero(known_values)[0]
要查找所有未知值的结果,我们使用known_values
数组上的np.cumsum
函数。布尔值被解释为0
或1
,因此这给出了以下数组:
acc = np.cumsum(known_values)
将为您的示例生成以下内容:
[ 0 1 2 2 3 4 5 6 7 8 9 10 11]
。
现在,known_idx[acc - 1]
将包含每个点的最后已知值的索引。使用low_values[known_idx[acc - 1]]
,如果上一个已知值低于True
,则会获得-1.0
;如果高于False
,则会获得-0.3
:
result = low_values[known_idx[acc - 1]]
还有一个问题:如果初始值低于-1.0
或高于-0.3
,那么一切都很好。但如果它介于两者之间,那么它将取决于它的左邻居 - 它没有。因此,在您的情况下,您只需将其定义为零。
我们可以通过检查acc[0]
是否等于0
或1
来实现。如果acc[0] = 1
,则一切正常,但如果acc[0] = 0
,则表示第一个值介于-1.0
和-0.3
之间,因此我们必须将其设置为零:
if not acc[0]:
result[0] = False
最后,由于我们进行了大量的比较,我们的result
数组是一个布尔数组。要将其转换为整数0
和1
,我们只需调用
result = np.int8(result)
我们得到了我们想要的结果:
array([0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0], dtype=int8)