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

如何用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的分组功能,结合连续区间标记实现,步骤如下:

  1. 标记连续区间分组键
    先区分每行的类型(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()
    
  2. 分组提取极值行
    针对每个分组,根据类型提取对应列的极值所在行:

    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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 05:54:22