如何用Pandas获取DataFrame中连续NaN区间的high/low极值?
问题描述
我正在处理如下结构的DataFrame:
datetime high low 1 2022-08-26 19:00:00+00:00 NaN 0.99564 6 2022-08-26 14:00:00+00:00 1.00902 NaN 9 2022-08-26 11:00:00+00:00 NaN 0.99860 10 2022-08-26 10:00:00+00:00 1.00238 NaN 14 2022-08-26 06:00:00+00:00 NaN 0.99466 17 2022-08-26 03:00:00+00:00 0.99748 NaN 22 2022-08-25 22:00:00+00:00 0.99772 NaN 25 2022-08-25 19:00:00+00:00 0.99790 NaN 27 2022-08-25 17:00:00+00:00 0.99752 NaN 28 2022-08-25 16:00:00+00:00 NaN 0.99492 30 2022-08-25 14:00:00+00:00 1.00006 NaN 31 2022-08-25 13:00:00+00:00 NaN 0.99555 38 2022-08-25 06:00:00+00:00 1.00336 NaN 40 2022-08-25 04:00:00+00:00 1.00088 NaN 43 2022-08-25 01:00:00+00:00 0.99929 NaN 44 2022-08-25 00:00:00+00:00 NaN 0.99632 47 2022-08-24 21:00:00+00:00 NaN 0.99636
期望得到如下输出:
datetime high low 1 2022-08-26 19:00:00+00:00 NaN 0.99564 6 2022-08-26 14:00:00+00:00 1.00902 NaN 9 2022-08-26 11:00:00+00:00 NaN 0.99860 10 2022-08-26 10:00:00+00:00 1.00238 NaN 14 2022-08-26 06:00:00+00:00 NaN 0.99466 25 2022-08-25 19:00:00+00:00 0.99790 NaN 28 2022-08-25 16:00:00+00:00 NaN 0.99492 30 2022-08-25 14:00:00+00:00 1.00006 NaN 31 2022-08-25 13:00:00+00:00 NaN 0.99555 38 2022-08-25 06:00:00+00:00 1.00336 NaN 44 2022-08-25 00:00:00+00:00 NaN 0.99632
具体需求:针对每一段连续的high为NaN(对应取low的最小值)或low为NaN(对应取high的最大值)的区间,获取该区间内的极值行,而非全局极值。想找一种简洁的Pandas实现方式,替代分块处理的方法。
解决方案
可以通过Pandas的分组功能,结合连续区间标记实现,步骤如下:
标记连续区间分组键
先区分每行的类型(high非空/low非空),再通过类型变化生成连续区间的分组ID:# 标记类型:1代表high非空(low为空),0代表low非空(high为空) df['group_type'] = df['high'].notna().astype(int) # 生成连续区间的分组ID:类型变化时ID递增 df['group_id'] = (df['group_type'] != df['group_type'].shift()).cumsum()分组提取极值行
针对每个分组,根据类型提取对应列的极值所在行:def extract_extreme(group): if group['group_type'].iloc[0] == 1: # high非空组,取high最大值对应的行 return group[group['high'] == group['high'].max()] else: # low非空组,取low最小值对应的行 return group[group['low'] == group['low'].min()] # 应用函数并合并结果,移除辅助列 result = df.groupby('group_id').apply(extract_extreme).reset_index(drop=True) result = result.drop(['group_type', 'group_id'], axis=1)
运行上述代码后,result即为期望的输出结果。
内容的提问来源于stack exchange,提问作者som3k
相关产品推荐
相关产品推荐

