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

如何简化类正弦波数据的波峰波谷提取与箱线图绘制流程?

简化类正弦波峰谷波动分析的代码流程

问题背景

我正在分析类正弦波形式的温度时序数据波动,目前已有可行方案,但代码流程太繁琐:需要分别创建波峰、波谷的DataFrame,再和主数据合并,最后生成差值序列绘制箱线图。我想知道是否必须创建这两个DataFrame?这类简单操作的代码量实在没必要这么大。

我的核心需求是对比随时间变化的温度波动,后续还要实现不同时段(比如2021年12月与2022年12月)的数据对比。以下是我用Scipy心电数据做的示例(模拟温度数据):

原冗余代码

import pandas as pd
from scipy.datasets import electrocardiogram
from scipy.signal import find_peaks
from scipy import ndimage

# 加载并预处理数据
temp = electrocardiogram()[200:300]
temp = ndimage.gaussian_filter1d(temp, 2)  # 修正原代码笔误:x改为temp
peaks, _ = find_peaks(temp)
troughs, _ = find_peaks(-temp)

# 创建波谷、波峰的DataFrame
troughs_df = pd.DataFrame()
troughs_df.index = troughs
troughs_df['troughs'] = 'trough'

peaks_df = pd.DataFrame()
peaks_df.index = peaks
peaks_df['peaks'] = 'peak'

# 合并主数据与峰谷DataFrame
temp_series = pd.Series(temp, name='temp')
temp = pd.merge(temp_series, troughs_df, left_index=True, right_index=True, how='outer')
temp = pd.merge(temp, peaks_df, left_index=True, right_index=True, how='outer')

# 标记峰谷并计算差值画箱线图
temp['peaks and troughs'] = temp[['peaks', 'troughs']].fillna('').sum(axis=1)
temp.query("`peaks and troughs` != ''")['temp'].diff().plot.box()

输入数据(Scipy心电切片)

array([ 0.125,  0.16 ,  0.165,  0.17 ,  0.185,  0.22 ,  0.225,  0.235,
        0.22 ,  0.23 ,  0.25 ,  0.28 ,  0.27 ,  0.25 ,  0.255,  0.245,
        0.235,  0.235,  0.25 ,  0.23 ,  0.245,  0.23 ,  0.22 ,  0.215,
        0.18 ,  0.12 ,  0.075,  0.065,  0.06 ,  0.055,  0.025, -0.005,
       -0.04 , -0.085, -0.135, -0.145, -0.14 , -0.12 , -0.12 , -0.16 ,
       -0.195, -0.2  , -0.215, -0.2  , -0.2  , -0.215, -0.255, -0.27 ,
       -0.225, -0.225, -0.24 , -0.25 , -0.23 , -0.19 , -0.18 , -0.2  ,
       -0.21 , -0.215, -0.21 , -0.21 , -0.205, -0.225, -0.23 , -0.24 ,
       -0.245, -0.23 , -0.23 , -0.21 , -0.2  , -0.185, -0.175, -0.175,
       -0.19 , -0.19 , -0.19 , -0.2  , -0.175, -0.13 , -0.09 , -0.095,
       -0.13 , -0.17 , -0.16 , -0.135, -0.1  , -0.09 , -0.115, -0.115,
       -0.08 , -0.04 , -0.065, -0.105, -0.12 , -0.12 , -0.11 , -0.105,
       -0.11 , -0.15 , -0.155, -0.16 ])

原代码输出的峰谷标记结果

temp troughs peaks peaks and troughs
13  0.3000     NaN  peak              peak
48 -0.2000  trough   NaN            trough
56 -0.2000     NaN  peak              peak
63 -0.2000  trough   NaN            trough
89 -0.1000     NaN  peak              peak

简化方案:无需创建额外DataFrame

完全不需要单独创建峰谷的DataFrame,直接合并峰谷的索引,提取对应的值后计算差值即可,代码量大幅减少:

简化后的代码

import pandas as pd
from scipy.datasets import electrocardiogram
from scipy.signal import find_peaks
from scipy import ndimage

# 数据加载与预处理
temp = electrocardiogram()[200:300]
temp = ndimage.gaussian_filter1d(temp, 2)
peaks, _ = find_peaks(temp)
troughs, _ = find_peaks(-temp)

# 合并峰谷索引并排序,提取对应值
all_extrema_indices = sorted(list(peaks) + list(troughs))
extrema_values = pd.Series(temp[all_extrema_indices], index=all_extrema_indices, name='temp')

# 计算差值并绘制箱线图
extrema_values.diff().dropna().plot.box()

简化说明

  1. 跳过冗余DataFrame创建:直接把峰谷索引合并后排序,用NumPy索引直接提取对应的数据点,无需多次merge操作。
  2. 逻辑更直接:核心需求是获取峰谷的差值,不需要额外标记"peak"/"trough"(如果后续需要标记,也可以用一行代码完成,完全不需要单独建DataFrame)。
  3. 兼容后续时段对比:如果要对比不同时段的数据,只需对每个时段重复上述简化流程,再把多个差值序列合并后绘制箱线图即可,代码结构依然简洁。

简化代码的核心输出

和原代码一致,最终会生成相同的箱线图:
箱线图


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 07:44:54