Python中阈值检测功能的实现

时间:2018-11-23 10:55:02

标签: python numpy

我想在Python中实现以下触发功能:

输入:

  • 时间向量t [n维numpy向量]
  • 数据向量y [n维numpy向量](值对应于t向量)
  • 阈值tr [float]
  • 阈值类型向量tr_type [int值的m维列表]

输出:

  • 阈值时间向量tr_time [浮点值的m维列表]

功能:

我想返回tr_time,它由y穿越tr的确切时间值组成(最好在下面的代码中也进行内插),y穿越tr的时间(穿越的意思是从小到小然后再到大) 。 tr_time中的不同值对应于tr_type向量:tr_type的元素指示交叉点的数量,以及这是上行还是下行交叉。例如1表示第一时间y从小于tr到大于tr,-3表示第三时间y从大于tr到小于tr(第三时间表示沿着时间矢量t)

目前我有下一个代码:

import numpy as np
import matplotlib.pyplot as plt


def trigger(t, y, tr, tr_type):
    triggermarker = np.diff(1 * (y > tr))
    positiveindices = [i for i, x in enumerate(triggermarker) if x == 1]
    negativeindices = [i for i, x in enumerate(triggermarker) if x == -1]
    triggertime = []
    for i in tr_type:
        if i >= 0:
            triggertime.append(t[positiveindices[i - 1]])
        elif i < 0:
            triggertime.append(t[negativeindices[i - 1]])
    return triggertime


t = np.linspace(0, 20, 1000)
y = np.sin(t)
tr = 0.5
tr_type = [1, 2, -2]
print(trigger(t, y, tr, tr_type))
plt.plot(t, y)
plt.grid()

现在,我对Python还是一个新手,所以我想知道是否有更Pythonic和更有效的方法来实现这一点。例如,无需for循环或无需编写单独的代码即可进行上行或下行穿越。

1 个答案:

答案 0 :(得分:1)

您可以使用两个遮罩:第一个遮罩分隔阈值以下和以上的值,第二个遮罩在第一个遮罩上使用np.diff:如果i和i + 1值都小于或大于阈值np .diff产生0:

import numpy as np
import matplotlib.pyplot as plt
t = np.linspace(0, 8 * np.pi, 400)
y = np.sin(t)
th = 0.5

mask = np.diff(1 * (y > th) != 0)
plt.plot(t, y, 'bx', markersize=3)
plt.plot(t[:-1][mask], y[:-1][mask], 'go', markersize=8)

output

使用切片[:-1]将产生超过阈值的“紧接之前”索引(您可以在图表中看到)。如果您希望索引“紧随其后”,请使用[1:]代替[:-1]