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

基于Python与SciPy的车速数据峰值检测问题:无法识别目标加速峰值

车速-时间数据的峰值检测问题排查与解决

需求说明

我有一组车速-时间数据(Y轴为车速,X轴为时间),需要统计车辆的加速次数,检测的峰值需满足:

  • 峰值前的低值处于0-13区间
  • 峰值数值处于20-25区间

我尝试用Python结合numpy、SciPy工具实现,但代码无法正确检测到预期的5个峰值,希望得到问题排查与解决方法。

原代码

import numpy as np
from scipy.signal import find_peaks, find_peaks_cwt
import matplotlib.pyplot as plt
x=np.array([ 0, 14,  9,  0,  0,  7,  0,  0, 12, 16, 15, 11,  7, 20, 24, 13, 13,
       14, 19, 13, 12, 10,  7,  3,  3,  3, 25, 14, 14, 14,  7, 24, 20, 20,
       21, 20, 20, 20, 20, 20, 21, 16, 11, 11, 18, 22, 22, 20, 19, 19, 18,
       15, 20, 23, 21, 23, 24, 15, 16, 19, 25, 24,  0, 20, 23, 24, 23, 22,
       21, 23, 25, 28, 24, 23, 23, 17,  7, 11, 21, 25, 25, 25, 25, 25, 25,
       15, 13,  9,  0, 21, 10, 18, 25, 25, 26, 23, 25, 23, 25, 27, 25, 12,
        0,  0,  0, 19, 22, 24, 25, 25, 24, 24, 23, 23, 16, 19, 23, 24, 24,
       17,  8,  0,  9,  7, 11, 18, 20, 23, 23, 24, 25, 25, 25, 17, 24, 24])

zero_locs = np.where(x<13 ) # find zeros in x
search_lims = np.append(zero_locs, len(x)) # limits for search area

diff_x = np.diff(x) # find the derivative of x
diff_x_mapped = diff_x >13   # find the max's of x (zero crossover 

peak_locs = []

for i in range(len(search_lims)-2):
    peak_loc = search_lims[i] + np.where(diff_x_mapped[search_lims[i]:search_lims[i+1]]==0)[0][0]
    if x[peak_loc] > 20 and x[peak_loc] <25:
        peak_locs.append(peak_loc)
fig= plt.figure(figsize=(19,5))
plt.plot(x)
plt.xlim(0,100)
plt.plot(np.array(peak_locs), x[np.array(peak_locs)], "x", color = 'r'

问题排查

  • 搜索区间划分错误:原代码用x<13的所有位置作为搜索区间起点,导致区间划分过于细碎,无法定位到“加速前的低值段”,反而干扰峰值搜索。
  • 峰值检测逻辑错误:通过导数大于13再找0值的方式完全偏离局部峰值的检测逻辑,大部分正常加速的增速不会达到13,且导数为0的点不一定是峰值。
  • 索引与循环逻辑问题:循环范围len(search_lims)-2无合理依据,且直接取np.where(...)的第一个结果,容易误判位置,甚至出现索引越界。
  • 条件验证不完整:仅判断峰值数值范围,未验证峰值前是否存在符合要求的0-13低值段,导致不符合条件的峰值被误判或符合条件的被遗漏。

解决方法

采用先找局部峰值,再验证前置条件的思路,步骤如下:

  1. 用find_peaks找出所有处于20-25区间的局部峰值
  2. 对每个峰值,检查其之前是否存在连续的0-13区间的低值(即加速前的稳定状态)
  3. 过滤出完全符合条件的峰值

修正后的代码

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

# 车速数据
x = np.array([ 0, 14,  9,  0,  0,  7,  0,  0, 12, 16, 15, 11,  7, 20, 24, 13, 13,
       14, 19, 13, 12, 10,  7,  3,  3,  3, 25, 14, 14, 14,  7, 24, 20, 20,
       21, 20, 20, 20, 20, 20, 21, 16, 11, 11, 18, 22, 22, 20, 19, 19, 18,
       15, 20, 23, 21, 23, 24, 15, 16, 19, 25, 24,  0, 20, 23, 24, 23, 22,
       21, 23, 25, 28, 24, 23, 23, 17,  7, 11, 21, 25, 25, 25, 25, 25, 25,
       15, 13,  9,  0, 21, 10, 18, 25, 25, 26, 23, 25, 23, 25, 27, 25, 12,
        0,  0,  0, 19, 22, 24, 25, 25, 24, 24, 23, 23, 16, 19, 23, 24, 24,
       17,  8,  0,  9,  7, 11, 18, 20, 23, 23, 24, 25, 25, 25, 17, 24, 24])

# 第一步:找出所有处于20-25区间的局部峰值
# 设置height参数限定峰值范围,prominence确保是有显著凸起的峰值
peaks, _ = find_peaks(x, height=(20, 25), prominence=2)

# 第二步:过滤出峰值前存在0-13低值段的峰值
valid_peaks = []
for peak in peaks:
    # 取峰值前的所有数据,检查是否存在连续的0-13区间
    prev_data = x[:peak]
    low_zones = np.where((prev_data >=0) & (prev_data <=13))[0]
    if len(low_zones) > 0:
        # 取最后一个低值点,确保是最近的加速前状态
        last_low_idx = low_zones[-1]
        # 验证低值点到峰值之间是连续加速过程,无回落的高值
        if np.all(x[last_low_idx+1:peak] >13) or (peak - last_low_idx) <=5:
            valid_peaks.append(peak)

# 可视化结果
fig = plt.figure(figsize=(19,5))
plt.plot(x)
plt.xlim(0, len(x))
plt.plot(np.array(valid_peaks), x[np.array(valid_peaks)], "x", color='r', markersize=12)
plt.title('Valid Acceleration Peaks')
plt.show()

print(f"检测到符合条件的峰值数量:{len(valid_peaks)}")

代码说明

  • find_peaks的height参数直接限定峰值在20-25区间,prominence过滤掉微小波动,确保是真正的加速峰值。
  • 对每个峰值,检查其之前是否存在0-13的低值段,且低值段到峰值之间是连续加速过程,确保符合“峰值前的低值”要求。
  • 可视化结果清晰标记所有符合条件的峰值,最终可得到预期的5个有效峰值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 22:55:29