如何自动识别时间序列中看到的“斜坡”的开始和停止时间?

信息处理 Python 时间序列 峰值检测
2022-02-08 14:53:13

我正在分析以 1Hz 采样的压力数据。时间序列表现出“斜坡”(压力线性增加,然后突然下降),我想自动检测开始和停止时间。请注意,这些压力事件不是周期性的:

在此处输入图像描述

我的第一次尝试是find_peaks在我的数据的平滑版本上使用 SciPy 的函数。

我首先使用SciPy's cookbook中描述的函数来平滑这些时间序列

smoothed_pressure = smooth(df['Pressure'], window_len=21)

在此处输入图像描述

然后我申请find_peaks找到mean_amplitude平滑数据上方的最大峰值(红色)和该幅度下方的最小峰值(黄色):

mean_amplitude = np.mean(smoothed_pressure)
max_indices = find_peaks(smoothed_pressure, distance=200, height=mean_amplitude)[0]
min_indices = find_peaks(smoothed_pressure, distance=200, height=[0,mean_amplitude])[0]

plt.figure(figsize=(20,3))
plt.title(filename)
plt.plot(df['Time'], df["Pressure"])
plt.scatter(df[df.index.isin(max_indices-11)]['Time'], df[df.index.isin(max_indices-11)]["Pressure"], color='red', zorder=5)
plt.scatter(df[df.index.isin(min_indices-11)]['Time'], df[df.index.isin(min_indices-11)]["Pressure"], color='yellow', zorder=5)

在此处输入图像描述

在调整之后,distance我设法让这个策略适用于这个特定的例子,但是这个解决方案不够健壮,并且在应用于其他数据集时会失败。

我正在寻找其他策略来解决这个问题。

我正在考虑在尝试识别峰值之前区分数据。我也愿意尝试机器学习策略。欢迎任何其他想法!

-------------------------------------------------- -------------------------------------------------- --------

编辑:实施MAXTRON的解决方案

正如 Maxtron 在下面的回答中所建议的那样,计算二阶导数是确定每个斜坡的停止时间的绝佳方法。

在下面的示例中,我将二阶导数应用于原始数据的(高度)平滑版本:

ds=pd.DataFrame()
mylength=61
smoothed_time = smooth(df['Time'], window_len=mylength)
smoothed_pressure = smooth(df['Pressure'], window_len=mylength)
ds['Pressure']=smoothed_pressure
ds['Time']=smoothed_time

然后我计算这个平滑信号的一阶和二阶导数:

ds['Pressure_first_derivative']=ds['Pressure'].diff() / ds['Time'].diff()
ds['Pressure_second_derivative']=ds['Pressure_first_derivative'].diff() / ds['Time'].diff()

二阶导数如下所示:

在此处输入图像描述

识别超过用户定义阈值 0.15 的样本是识别每个斜坡结束的良好起点:

max_indices=ds[ds['Pressure_second_derivative']>0.15].index-np.int(mylength/2)

在此处输入图像描述

可能有一些方法可以使阈值自动化。此外,由于每个峰值的多个样本超过了这个阈值,我认为find_peaks仍然需要将每组点归结为一个样本。

1个回答

斜坡函数的二阶导数是 delta 函数。所以本质上,你可以通过对原始信号进行二阶导数来构造一个新信号。

方法:如果原始信号,则二阶导数为xx(0),,x(N1)

y[t]=x[t]2x[t1]+x[t2],2t<N

二阶导数在斜坡信号结束时是稀疏的。find_peaks使用二阶导数信号时可以避免函数。应用简单的阈值技术应该可以帮助您找到峰值的位置。