如何反向使用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()
关键说明
- 峰谷排序:将
peaks和troughs合并后排序,确保所有极值点按时间顺序排列,避免原代码中zip配对可能导致的区间遗漏。 - 上升段判断:通过比较相邻极值点的滚动平均值大小,确定是否为上升段(后点值大于前点值)。
- 区间填充:用
ax.axvspan填充上升段区间,同时用红色线标记上升段起点(谷)、绿色线标记终点(峰),完全匹配你需要的高亮逻辑。
内容的提问来源于stack exchange,提问作者aholtz
相关产品推荐
相关产品推荐

