当前位置: 首页 > 知识库问答 >
问题:

不均匀间隔时间序列中的峰值检测

司空宗清
2023-03-14

我正在使用一个数据集,其中包含与datetime相结合的度量值,例如:

datetime value
2017-01-01 00:01:00,32.7
2017-01-01 00:03:00,37.8
2017-01-01 00:04:05,35.0
2017-01-01 00:05:37,101.1
2017-01-01 00:07:00,39.1
2017-01-01 00:09:00,38.9

我试图检测和删除可能出现的潜在峰值,如2017-01-01 00:05:37,101.1度量值。

到目前为止,我发现了一些东西:

>

  • 这个数据集的时间间隔从15秒一直到25分钟,这使得它非常不均匀
  • 峰的宽度无法事先确定
  • 峰值高度与其他值明显偏离
  • 时间步长的标准化只应在去除异常值后进行,因为它们会干扰结果

    由于其他异常(例如,负值、平线),即使没有这些异常,也“不可能”使其变得均匀,因为峰值会产生错误的值;

    • 在这个问题上,我忘了提到时间间隔不均匀的临界点。

    我到处找了,什么也没找到。实现将使用Python,但我愿意深入研究其他语言以获得逻辑。

  • 共有1个答案

    公冶谦
    2023-03-14

    我已经在github上发布了这段代码给未来有这个问题或类似问题的任何人。

    经过多次尝试和错误,我认为我创造了一些行之有效的东西。使用@user58697告诉我的内容,我成功地创建了一个代码来检测阈值之间的每个峰值。

    通过使用他/她解释的逻辑if((flow[i 1]-flow[i])/(time[i 1]-time[i])

    从阅读开始。csv并解析日期,然后拆分为两个numpy数组:

    dataset = pd.read_csv('https://raw.githubusercontent.com/MigasTigas/peak_removal/master/dataset_simple_example.csv', parse_dates=['date'])
    
    dataset = dataset.sort_values(by=['date']).reset_index(drop=True).to_numpy()  # Sort and convert to numpy array
    
    # Split into 2 arrays
    values = [float(i[1]) for i in dataset]  # Flow values, in float
    values = np.array(values)
    
    dates = [i[0].to_pydatetime() for i in dataset]
    dates = np.array(dates)
    

    然后将(流[i 1]-流[i])/(时间[i 1]-时间[i])应用于整个数据集:

    flow = np.diff(values)
    time = np.diff(dates).tolist()
    time = np.divide(time, np.power(10, 9))
    
    slopes = np.divide(flow, time) # (flow[i+1] - flow[i]) / (time[i+1] - time[i])
    slopes = np.insert(slopes, 0, 0, axis=0) # Since we "lose" the first index, this one is 0, just for alignments
    

    最后,为了检测峰值,我们将数据减少到每个x秒的滚动窗口。这样我们就可以很容易地检测到它们:

    # ROLLING WINDOW
    size = len(dataset)
    rolling_window = []
    rolling_window_indexes = []
    RW = []
    RWi = []
    window_size = 240  # Seconds
    
    dates = [i.to_pydatetime() for i in dataset['date']]
    dates = np.array(dates)
    
    # create the rollings windows
    for line in range(size):
        limit_stamp = dates[line] + datetime.timedelta(seconds=window_size)
        for subline in range(line, size, 1):
            if dates[subline] <= limit_stamp:
    
                rolling_window.append(slopes[subline])  # Values of the slopes
                rolling_window_indexes.append(subline)  # Indexes of the respective values
    
            else:
    
                RW.append(rolling_window)
                if line != size: # To prevent clearing the last rolling window
                    rolling_window = []
    
                RWi.append(rolling_window_indexes)
                if line != size:
                    rolling_window_indexes = []
    
                break
    else:
        # To get the last rolling window since it breaks before append
        RW.append(rolling_window)
        RWi.append(rolling_window_indexes)
    

    在获得所有滚动窗口后,我们开始享受乐趣:

    t = 0.3  # Threshold
    peaks = []
    
    for index, rollWin in enumerate(RW):
        if rollWin[0] > t: # If the first value is greater of threshold
            top = rollWin[0] # Sets as a possible peak
            bottom = np.min(rollWin) # Finds the minimum of the peak
    
            if bottom < -t: # If less than the negative threshold
                bottomIndex = int(np.argmin(rollWin)) # Find it's index
    
                for peak in range(0, bottomIndex, 1): # Appends all points between the first index of the rolling window until the bottomIndex
                    peaks.append(RWi[index][peak]) 
    
    

    这段代码背后的思想是,每个峰值都有上升和下降,如果两者都大于规定的阈值,那么它就是一个异常峰值以及它们之间的所有峰值:

     类似资料:
    • 问题内容: 我有两个numpy数组light_points和time_points,想对这些数据使用一些时间序列分析方法。 然后我尝试了这个: 这有效,但没有做正确的事。确实,测量值不是均匀地间隔开的,如果我只是将time_points pandas DataFrame声明为帧的索引,则会出现错误: 我不知道该如何纠正。另外,似乎不建议使用大熊猫。 我尝试了这个: 但这给了我长度上的不匹配: 但是

    • 我一直试图实时检测正弦时间序列数据中的峰值,但迄今为止没有成功。我似乎找不到一种能够以合理的精度检测正弦信号峰值的实时算法。我要么没有检测到峰值,要么正弦波上有无数个点被检测为峰值。 对于类似正弦波且可能包含一些随机噪声的输入信号,什么是好的实时算法? 作为一个简单的测试案例,考虑一个稳定的正弦波,它总是相同的频率和振幅。(确切的频率和振幅并不重要;我任意选择了60赫兹的频率,振幅为/− 使用Je

    • 谁会有一个好的算法来使用Swift(v3)测量不断增长的时间序列数据的峰值?因此,在数据流入时检测峰值。 例如,平滑z波算法的快速版本。那个算法似乎是合适的。 我需要检测如下所示的峰值。数据包含正数和负数。输出应该是峰值的计数器,和/或该特定样本的真/假。 示例数据集(上一系列的摘要): 最新消息:感谢Jean Paul首次提供Swift端口。但不确定z-wave算法是否适合此数据集

    • 我有一个带有开/关数据的二进制时间序列数据集。on通常是短暂的,因此看起来像一个峰值。这就是它的样子。 我已经检测到了峰值,并提取了峰值之间的时间间隔,并且也有数据(底部的红色小双向箭头)。问题是,可以看出,峰值是聚集的,我想对突发大小(集群中的峰值数量)、突发间隔(第一个集群的最后一个峰值和最后一个集群的第一个峰值之间的距离)、突发数量等进行量化。 一旦确定了集群,所有这些都很容易做到。这可以通

    • 问题内容: 我正在尝试学习SQL,所以请耐心等待。我正在使用PostgreSQL 9.3 我想根据日期窗口对一列进行平均。我能够编写窗口函数来完成一个集合,但是我希望能够随着不断增长做到这一点。我的意思是: 我假设有一个比对我要平均的每个范围运行查询更好的方法。任何建议表示赞赏。谢谢你。 编辑 我正在尝试创建均匀分布的垃圾箱,以用于汇总表的值。 我的间隔是: 这里是一个表的列 并且 是并列我想表分

    • 问题内容: 时间间隔后如何调用方法?例如,如果要在2秒钟后在屏幕上打印声明,其程序是什么? 问题答案: 答案是一起使用javax.swing.Timer和java.util.Timer: 显然,仅使用java.util.Timer可以达到2秒的打印间隔,但是如果要在一次打印后停止打印,那将很难。 另外,请勿在代码中混用线程,而无需线程即可! 希望这会有所帮助!