python中的时间序列分段

python中的时间序列分段,python,time-series,segment,Python,Time Series,Segment,我正在尝试分割如图所示的时间序列数据。我有很多来自传感器的数据,这些数据中的任何一个都可能有不同数量的孤立峰区域。在这个图中,我有三个。我希望有一个函数,它将时间序列作为输入,并返回等长的分段部分 我最初的想法是有一个滑动窗口来计算振幅的相对变化。由于具有峰值的窗口将具有相对较高的变化,我可以为相对变化定义某个阈值,这将帮助我获得具有孤立峰值的窗口。然而,这将在选择阈值时产生问题,因为相对变化对数据中的噪声非常敏感 有什么建议吗 1,这取决于你想如何定义一个区域,但看起来你只是有感觉,而不是严

我正在尝试分割如图所示的时间序列数据。我有很多来自传感器的数据,这些数据中的任何一个都可能有不同数量的孤立峰区域。在这个图中,我有三个。我希望有一个函数,它将时间序列作为输入,并返回等长的分段部分

我最初的想法是有一个滑动窗口来计算振幅的相对变化。由于具有峰值的窗口将具有相对较高的变化,我可以为相对变化定义某个阈值,这将帮助我获得具有孤立峰值的窗口。然而,这将在选择阈值时产生问题,因为相对变化对数据中的噪声非常敏感

有什么建议吗


1,这取决于你想如何定义一个区域,但看起来你只是有感觉,而不是严格的定义。如果你有一个非常清晰的定义,你想剪出什么样的作品,你可以尝试一些方法,比如匹配过滤器

2,您可能需要检测绝对幅值的峰值。如果不工作,尝试一阶差的绝对幅值峰值,甚至二阶

3、这样的噪声数据很难处理。我的建议是在提取未过滤数据的部分之前进行过滤。过滤将给你平滑的峰,这样峰的位置可以通过导数符号的变化来检测。对于过滤,请先尝试使用低通滤波器。如果它不起作用,我也建议希尔伯特-黄变换


*,看起来您正在使用matlab。所提到的方法都包含在matlab中。

要做到这一点,您需要找出噪声中的信号

获取信号的平均值,并添加一些多人游戏,将边界放置在噪波绿色虚线的顶部和底部 查找噪波底部下方的峰值->数组2组数据 查找噪波顶部的峰值->数组2组数据 获取底部第一峰的最小指数和顶部第一峰的最大指数,以找到第一峰范围 获取顶部第二峰的最小指数和底部第二峰的最大指数,以找到第二峰范围 代码中的一些描述。用这种方法你可以找到其他的峰。 您需要手动输入的一件事是告诉程序峰值之间的X值,以便将数据拆分为多个部分

有关摘要,请参见图

import numpy as np
from matplotlib import pyplot as plt


# create noise data
def function(x, noise):
    y = np.sin(7*x+2) + noise
    return y

def function2(x, noise):
    y = np.sin(6*x+2) + noise
    return y


noise = np.random.uniform(low=-0.3, high=0.3, size=(100,))
x_line0 = np.linspace(1.95,2.85,100)
y_line0 = function(x_line0, noise)
x_line = np.linspace(0, 1.95, 100)
x_line2 = np.linspace(2.85, 3.95, 100)
x_pik = np.linspace(3.95, 5, 100)
y_pik = function2(x_pik, noise)
x_line3 = np.linspace(5, 6, 100)

# concatenate noise data
x = np.linspace(0, 6, 500)
y = np.concatenate((noise, y_line0, noise, y_pik, noise), axis=0)

# plot data
noise_band = 1.1
top_noise = y.mean()+noise_band*np.amax(noise)
bottom_noise = y.mean()-noise_band*np.amax(noise)
fig, ax = plt.subplots()
ax.axhline(y=y.mean(), color='red', linestyle='--')
ax.axhline(y=top_noise, linestyle='--', color='green')
ax.axhline(y=bottom_noise, linestyle='--', color='green')
ax.plot(x, y)

# split data into 2 signals
def split(arr, cond):
  return [arr[cond], arr[~cond]]

# find bottom noise data indexes
botom_data_indexes = np.argwhere(y < bottom_noise)
# split by visual x value
splitted_bottom_data = split(botom_data_indexes, botom_data_indexes < np.argmax(x > 3))

# find top noise data indexes
top_data_indexes = np.argwhere(y > top_noise)
# split by visual x value
splitted_top_data = split(top_data_indexes, top_data_indexes < np.argmax(x > 3))

# get first signal range
first_signal_start = np.amin(splitted_bottom_data[0])
first_signal_end = np.amax(splitted_top_data[0])

# get x index of first signal
x_first_signal = np.take(x, [first_signal_start, first_signal_end])
ax.axvline(x=x_first_signal[0], color='orange')
ax.axvline(x=x_first_signal[1], color='orange')

# get second signal range
second_signal_start = np.amin(splitted_top_data[1])
second_signal_end = np.amax(splitted_bottom_data[1])

# get x index of first signal
x_second_signal = np.take(x, [second_signal_start, second_signal_end])
ax.axvline(x=x_second_signal[0], color='orange')
ax.axvline(x=x_second_signal[1], color='orange')

plt.show()
输出:

红线=所有数据的平均值

绿线-顶部和底部噪波边界

橙色线-选定峰值数据


你能发布输入数据吗?分段是指从泥炭开始到峰值结束的数据?没有带单位的轴的图形没有值。是的,我需要从峰值开始到结束的数据。我添加了带有轴的图形。我真的不知道如何添加输入数据。它是一个.txt文件。我看不到在这里附加它们的任何选项。您可以生成带有噪波的rangom测试数据来模拟您的数据。您需要如何存储这些数据段?在csv中?保存数据段并不是那么重要。我只需要找到一种方法,首先从连续数据中分割出来。数据来自加速度传感器。它记录了一段时间内的加速度读数。峰值表示在给定时间对传感器施加了一些力。在上图中,负载施加了三次,但有一定的时间延迟。此时间延迟随数据集的不同而变化。所以,我想对每个记录的峰值分别进行一些处理。为了做到这一点,我必须先把它们分开。@AashishShah不客气!如果你接受我的回答,我会很高兴的: