在 Numpy 数组中提取高于特定阈值的连续值

Extracting continuous values above a certain threshold in a Numpy array

对于一个学校项目,我需要实现以下功能:

创建一个函数 find_intervals(s, threshold),在输入中接收一个系列 s 和一个阈值。

找出信号高于给定阈值时的连续周期。

该函数应该 return 一个系列,该系列具有每个连续期间的开始日期作为索引,并且具有以天数表示的期间长度作为关联值。结果应按周期长度降序排列。

当应用于这样的信号时(thershold=0 的橙色线):

它应该return以下系列:

70     35
140    35
1      34
Name: interval, dtype: int64

也就是说,最大的间隔是35个单位,它从标签70开始,然后还有另一个长度为35的间隔,从140开始,等等。在练习中,索引将是一个日期和长度间隔以天数表示。

我写了下面的函数(在this Whosebug answer的帮助下)

def intervals(samples,threshold):
    samples = np.array(samples)
    start = -1
    intervals = []
    for idx,x in enumerate(samples):
        if start < 0 and abs(x) < threshold:
            start = idx
        elif start >= 0 and abs(x) >= threshold:
            dur = idx-start
            if dur >= 0:
                intervals.append((start))
            start = -1
    return intervals

但是,当我在类似的正弦波上调用这个函数时,该函数对阈值 0 或任何负值不起作用。我真的不明白为什么。

编辑:这是我的尝试和得到的结果;

在下面的部分中,我绘制了一个简单的 Sin 波。

x = np.arange(0,64*np.pi,1) 
y = np.sin(x/11)
df = pd.Series(data=y,index=x)
plt.plot(x,y)
df = np.array(df)

当我 运行 带有 intervals(df,0.5) 的代码时,我得到 [0, 34, 69, 103, 138, 172] 这是预期的。

但是;

如果我这样做; intervals(df,0) 我得到一个空列表,对于任何负阈值都可以说同样的事情。

将您的函数更改为:

def find_intervals2(samples, threshold):
    samp = samples[samples >= threshold]
    xx = samp.groupby((samp.index != samp.index.to_series().shift() + 1)
        .cumsum()).apply(lambda grp: (grp.index[0], grp.size))
    return pd.Series(xx.str[1].values, index=xx.str[0]).sort_values(ascending=False)

请注意,结果是 Series 而不是 list

为了提供一个更具指导意义的示例,将源系列定义为:

x = np.arange(0, 68 * np.pi, dtype=int)
y2 = np.sin(x / 11 * (1000 - x) // 7 / 142)
s2 = pd.Series(data=y2, index=x)
plt.plot(s2)
plt.grid(True);

注意图中“逐步降低”的频率。

那么当你 运行 find_intervals(s2, -0.2) 结果是:

162    52
72     48
0      39
dtype: int64