You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何反向使用scipy find_peaks识别时间序列上升段而非下降段?

时间序列滚动平均值的上升段高亮实现

你已经通过scipy.signal.find_peaks实现了下降段的高亮,要实现上升段(红色线到绿色线之间的区域填充),可以通过调整峰谷的配对逻辑来实现,具体修改如下:

修改后的代码

import matplotlib.pyplot as plt
import numpy as np
from scipy.signal import find_peaks

ax = df['x_rolling'].plot(figsize=(10, 5), use_index=True, ylabel='Net Sales (USD)')
plt.title('Order Net Sales (Rolling average: 4 weeks)')
ax.grid(axis='x', alpha=0.3)

w = 7
p = np.std(data2)
peaks, _ = find_peaks(df['x_rolling'], width=w, prominence=p)
troughs, _ = find_peaks(-df['x_rolling'], width=w, prominence=p)

# 合并所有峰谷索引并按时间顺序排序
all_extrema = np.sort(np.concatenate([peaks, troughs]))

# 遍历相邻极值点,判断并高亮上升段
for i in range(len(all_extrema) - 1):
    idx1, idx2 = all_extrema[i], all_extrema[i+1]
    val1, val2 = df['x_rolling'].iloc[idx1], df['x_rolling'].iloc[idx2]
    x1, x2 = df.iloc[idx1].name, df.iloc[idx2].name
    
    # 后值大于前值,判定为上升段
    if val2 > val1:
        ax.axvspan(x1, x2, facecolor='red', alpha=0.2)
        ax.axvline(x1, color='red', alpha=0.6)  # 标记上升段起点(谷)
        ax.axvline(x2, color='green', alpha=0.6)  # 标记上升段终点(峰)
    # 可选:保留下降段高亮,用不同颜色区分
    else:
        ax.axvspan(x1, x2, facecolor='blue', alpha=0.2)
        ax.axvline(x1, color='green', alpha=0.6)
        ax.axvline(x2, color='red', alpha=0.6)

# 去重图例
handles, labels = ax.get_legend_handles_labels()
unique_handles = dict(zip(labels, handles)).values()
ax.legend(unique_handles)

plt.show()

关键说明

  1. 峰谷排序:将peaks和troughs合并后排序,确保所有极值点按时间顺序排列,避免原代码中zip配对可能导致的区间遗漏。
  2. 上升段判断:通过比较相邻极值点的滚动平均值大小,确定是否为上升段(后点值大于前点值)。
  3. 区间填充:用ax.axvspan填充上升段区间,同时用红色线标记上升段起点(谷)、绿色线标记终点(峰),完全匹配你需要的高亮逻辑。

内容的提问来源于stack exchange,提问作者aholtz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 11:47:32