如何基于DataFrame的Vg_out列升降趋势拆分多个子DataFrame
按局部极值拆分DataFrame升降段的解决方案
核心思路
先通过趋势分析定位局部极值点,再基于极值点拆分出每个独立的上升/下降子DataFrame,同时处理连续相等的Vg_out值问题。
实现步骤与代码
import pandas as pd # 假设你的原始数据存储在df中 # 1. 计算Vg_out的差值,处理浮点精度问题 df['diff'] = df['Vg_out'].diff() # 标记趋势:1=上升,-1=下降,0=持平(用1e-9规避浮点误差) df['trend'] = df['diff'].apply(lambda x: 1 if x > 1e-9 else (-1 if x < -1e-9 else 0)) # 处理连续持平的情况:继承前一个非持平的趋势 df['trend'] = df['trend'].replace(0, method='ffill') df['trend'] = df['trend'].fillna(0) # 第一个数据点默认趋势为0 # 2. 检测趋势变化,定位局部极值 df['trend_change'] = df['trend'].diff() # 局部最大值:趋势从上升(1)转为下降(-1),对应变化前的点 local_max_idx = df[df['trend_change'] == -2].index - 1 # 局部最小值:趋势从下降(-1)转为上升(1),对应变化前的点 local_min_idx = df[df['trend_change'] == 2].index - 1 # 合并所有极值点并按索引排序 extremes = sorted(list(local_max_idx) + list(local_min_idx)) # 补充首尾索引,确保覆盖整个数据集 if extremes[0] != df.index[0]: extremes.insert(0, df.index[0]) if extremes[-1] != df.index[-1]: extremes.append(df.index[-1]) # 3. 拆分出每个升降段子DataFrame segments = [] for i in range(len(extremes) - 1): start_idx = extremes[i] end_idx = extremes[i + 1] # 提取子DataFrame并标记类型 segment = df.loc[start_idx:end_idx].copy() segment['segment_type'] = 'ascend' if segment['Vg_out'].iloc[-1] > segment['Vg_out'].iloc[0] else 'descend' segments.append(segment)
关键细节说明
- 浮点精度处理:用
1e-9作为差值判断阈值,避免因浮点计算误差导致的误判。 - 连续相等值处理:通过
ffill将连续持平的行继承前一个有效趋势,确保这类数据被归到正确的升降段中。 - 极值定位逻辑:通过趋势变化的差值(-2/2)精准定位局部极值,不会遗漏或误判极值点。
- 完整覆盖:补充首尾索引,保证原始DataFrame的所有数据都被拆分到对应的子段中。
内容的提问来源于stack exchange,提问作者hivzzz
相关产品推荐
相关产品推荐

