如何在含NaN的Pandas列中按规则提取极值(区分阵风/机动)
Pandas 非NaN数据段分类处理实现
核心思路
利用Pandas分组功能标记连续非NaN数据段,按段计算时长后,针对正负值分别提取对应极值(正取最大、负取最小),再根据时长阈值分配到maneuvers或gusts列表,全程基于DataFrame完成逻辑处理,避免低效循环。
代码实现
import pandas as pd # 假设你的DataFrame名为df,包含"Outside Dead Band"列 # 1. 为连续非NaN数据段生成唯一分组ID df['segment_id'] = df['Outside Dead Band'].isna().cumsum() # 过滤NaN行,仅保留有效数据段分组 valid_segments = df[df['Outside Dead Band'].notna()].groupby('segment_id') # 初始化结果列表 maneuvers = [] gusts = [] # 遍历处理每个数据段 for _, segment in valid_segments: # 计算段持续时长:数据点数量 / 采样率(32Hz) duration = len(segment) / 32 segment_values = segment['Outside Dead Band'] # 处理正数值部分 positive_vals = segment_values[segment_values > 0] if not positive_vals.empty: pos_max = positive_vals.max() maneuvers.append(pos_max) if duration > 2 else gusts.append(pos_max) # 处理负数值部分 negative_vals = segment_values[segment_values < 0] if not negative_vals.empty: neg_min = negative_vals.min() maneuvers.append(neg_min) if duration > 2 else gusts.append(neg_min) # 可选:删除临时生成的分组ID列 df.drop('segment_id', axis=1, inplace=True)
代码说明
- 分组标记:通过
isna().cumsum()实现,每次遇到NaN时分组ID递增,确保连续非NaN数据归为同一组。 - 时长计算:采样率为32Hz,数据段长度除以32即为持续秒数。
- 正负值分离:分别提取正、负数值并取对应极值,避免正负值互相干扰。
- 空值判断:处理全正或全负的数据段,防止空Series调用
max()/min()报错。
测试示例
import numpy as np # 构造测试数据:包含1秒正段、3秒负段、2秒混合段 test_data = np.concatenate([ np.full(32, 2.5), # 1秒正 → gusts [np.nan], np.full(96, -3.2), # 3秒负 → maneuvers [np.nan], np.concatenate([np.full(32, 1.8), np.full(32, -2.1)]), # 2秒混合 → gusts [np.nan] ]) df = pd.DataFrame({'Outside Dead Band': test_data})
运行代码后,maneuvers结果为[-3.2],gusts结果为[2.5, 1.8, -2.1],完全符合预期逻辑。
内容的提问来源于stack exchange,提问作者Benny
相关产品推荐
相关产品推荐

