在数组中找到多个感兴趣区域

3 投票
1 回答
551 浏览
提问于 2025-04-17 22:33

假设我做了一个实验,运行了一个Python程序很长时间。在这段时间里,我对某个量随时间的变化进行了多次测量。每次测量之间的间隔在1到3秒之间,而每次测量的时间步长要小得多,比如说0.01秒。假设我们只看y轴,数据可能长这样:

[...0,1,-1,4,1,0,0,2,3,1,0,-1,2,3,5,7,8,17,21,8,3,1,0,0,-2,-17,-20,-10,-3,3,1,0,-2,-1,1,0,0,1,-1,0,0,2,0...]

在这里,我们看到了一段静止期,接着是一个急剧上升,然后又急剧下降,接着在0附近稍微停顿一下,再急剧下降,最后又急剧上升,最后又回到0附近。点表示这是一个长数据流的一部分,数据在两个方向上延伸。整个数据集中会有很多这样的事件,它们的长度各不相同,之间夹杂着一些低幅度的区域。

我希望能形成一个包含'n'个array(或者tuple)的数组,这些数组的长度各不相同,专门用来捕捉这些事件,以便我可以单独分析它们。我不能仅仅通过np.absolute()这样的阈值来分隔,因为在某些事件中,偶尔会出现一些接近零的小区域,比如上面的例子。此外,测量之间可能会有一些短暂但幅度较大的波动。

上面的示例理想情况下应该能得到一些来自两侧平坦区域的元素。

[0,-1,2,3,5,7,8,17,21,8,3,1,0,0,-2,-17,-20,-10,-3,3,1,0,-2,-1]

我在想可以这样做:

输入:

[0,1,0,0,-1,4,8,22,16,7,2,1,0,-1,-17,-20,-6,-1,0,1,0,2,1,0,8,-7,-1,0,0,1,0,1,-1,-17,-22,-40,16,1,3,14,17,19,8,2,0,1,3,2,3,1,0,0,-2,1,0,0,-1,22,4,0,-1,0]

根据一些连续值小于2的数量进行分割。

[[-1,4,8,22,16,7,2,1,0,-1,-17,-20,-6,-1],[8,-7,-1,0],[-1,-17,-22,-40,16,1,3,14,17,19,8,2,0],[1,22,4,]]

就像这个图:

enter image description here

如果子数组的长度小于10,就把它们去掉:

[[-1,4,8,22,16,7,2,1,0,-1,-17,-20,-6,-1],[-1,-17,-22,-40,16,1,3,14,17,19,8,2,0]]

这样的方法好不好呢?第一步让我有点困惑,我还需要保留事件中的那些小幅度区域。

重新编辑!我将比较两个信号,每个信号都是随时间变化的,所以它们会被组合成一个元组列表。

1 个回答

1

这是我基于指数平滑法的一些看法。

import itertools
A=np.array([0,1,0,0,-1,4,8,22,16,7,2,1,0,-1,-17,-20,-6,-1,0,1,0,2,1,0,8,-7,-1,0,0,1,0,1,-1,-17,-22,-40,16,1,3,14,17,19,8,2,0,1,3,2,3,1,0,0,-2,1,0,0,-1,22,4,0,-1,0])
B=np.hstack(([0,0],A,[0,0]))
B=np.asanyarray(zip(*[B[i:] for i in range(5)]))
C=(B*[0.25,0.5,1,0.5,0.25]).mean(axis=1) #C is the 5-element sliding windows exponentially smoothed signal
D=[]
for item in itertools.groupby(enumerate(C), lambda x: abs(x[1])>1.5): 
    if item[0]:
        D.append(list(item[1])) #Get the indices where the signal are of magnitude >2. Change 1.5 to control the behavior.
E=[D[0]]
for item in D[1:]:
    if (item[0][0]-E[-1][-1][0]) <5: #Merge interesting regions if they are 5 or less indices apart. Change 5 to control the behavior.
        E[-1]=E[-1]+item
    else:
        E.append(item)
print [(item[0][0], item[-1][0]) for item in E]
[A[item[0][0]: item[-1][0]] for item in E if (item[-1][0]-item[0][0])>9] #Filter out the interesting regions <10 in length.

在这里输入图片描述

撰写回答