如何精准获取曲线峰值左右最低点以计算特定区域面积?
精准定位泳池泵频率峰值左右最低点的方案
针对你已识别出平滑后pulse数据峰值的情况,以下是几个避免假极小值、精准获取每个峰值左右最低点的实用方法:
1. 限定搜索区间(核心思路)
假极小值大多来自峰值以外的噪声波动,通过把每个峰值的搜索范围限制在相邻峰值之间,可从根源上排除无关区域干扰:
- 第i个峰值的左搜索区间:上一个峰值位置(或数据开头)到当前峰值
- 右搜索区间:当前峰值到下一个峰值位置(或数据结尾)
- 在区间内用
np.argmin直接定位最低点
示例代码:
import numpy as np # 已有的峰值索引数组、平滑后pulse数据 peak_indices = np.array([...]) smoothed_pulse = np.array([...]) left_min_indices = [] right_min_indices = [] for i, peak_idx in enumerate(peak_indices): # 处理左侧最低点 left_start = peak_indices[i-1] if i > 0 else 0 left_end = peak_idx left_min_pos = left_start + np.argmin(smoothed_pulse[left_start:left_end]) left_min_indices.append(left_min_pos) # 处理右侧最低点 right_end = peak_indices[i+1] if i < len(peak_indices)-1 else len(smoothed_pulse) right_start = peak_idx right_min_pos = right_start + np.argmin(smoothed_pulse[right_start:right_end]) right_min_indices.append(right_min_pos)
2. 阈值过滤假极小值
若区间内仍有噪声导致的微小波动(假极小值),可通过设定阈值过滤:
- 设定比例阈值(比如极小值需低于对应峰值的30%-50%,根据数据调整)
- 若找到的"最低点"高于阈值,向峰值方向遍历直到找到符合条件的点
示例代码:
threshold_ratio = 0.4 # 极小值需低于峰值的40% filtered_left_min = [] filtered_right_min = [] for i, peak_idx in enumerate(peak_indices): peak_val = smoothed_pulse[peak_idx] # 过滤左侧 current_left_idx = left_min_indices[i] current_left_val = smoothed_pulse[current_left_idx] left_start = peak_indices[i-1] if i > 0 else 0 while current_left_val > peak_val * threshold_ratio and current_left_idx > left_start: current_left_idx -= 1 current_left_val = smoothed_pulse[current_left_idx] filtered_left_min.append(current_left_idx) # 过滤右侧 current_right_idx = right_min_indices[i] current_right_val = smoothed_pulse[current_right_idx] right_end = peak_indices[i+1] if i < len(peak_indices)-1 else len(smoothed_pulse) while current_right_val > peak_val * threshold_ratio and current_right_idx < right_end: current_right_idx += 1 current_right_val = smoothed_pulse[current_right_idx] filtered_right_min.append(current_right_idx)
3. 结合pH值辅助验证
因为pulse的作用是维持pH低于7.4,当pH≥7.4时,泵频率应处于基线水平(即最低点),可利用这一业务逻辑辅助定位:
- 先提取所有pH≥7.4的索引作为基线候选点
- 为每个峰值找最近的左侧/右侧基线点,若无基线点则退回到区间内的最低点
示例代码:
ph_values = np.array([...]) # pH数据列 baseline_indices = np.where(ph_values >= 7.4)[0] # 定位左侧最低点 left_min_indices = [] for peak_idx in peak_indices: valid_baselines = baseline_indices[baseline_indices < peak_idx] if len(valid_baselines) > 0: left_min_idx = valid_baselines[-1] else: left_min_idx = np.argmin(smoothed_pulse[:peak_idx]) left_min_indices.append(left_min_idx) # 定位右侧最低点 right_min_indices = [] for peak_idx in peak_indices: valid_baselines = baseline_indices[baseline_indices > peak_idx] if len(valid_baselines) > 0: right_min_idx = valid_baselines[0] else: right_min_idx = peak_idx + np.argmin(smoothed_pulse[peak_idx:]) right_min_indices.append(right_min_idx)
组合使用建议
实际场景中可结合三个方法:先通过区间限定缩小搜索范围,再用pH基线验证锁定候选点,最后用阈值过滤排除剩余假极小值,最大程度保证定位精准性。
内容的提问来源于stack exchange,提问作者Samuele Auteri
相关产品推荐
相关产品推荐

