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

在Pandas分组DataFrame中获取前序最大及后序最小非缺失值

问题描述

我有一个带分组结构的Pandas DataFrame,其中目标列val在分组内已排序,但存在缺失值需要界定。原始数据如下:

group_id    id_within_group     val
1           1                   3.2  
1           2                   4.8
1           3                   5.2
1           4                   NaN
1           5                   7.5
2           1                   1.8
2           2                   2.8
2           3                   NaN
2           4                   5.4
2           5                   6.2

需要生成下界列max_prev(当前行所在分组中前序所有行的最大值)和min_next(当前行所在分组中后序所有行的最小值)。由于可能存在连续NaN,不能仅查看相邻行,无需处理分组内首尾行的边界情况,期望输出如下:

group_id    id_within_group     val     max_prev    min_next
1           1                   3.2     NaN         4.8
1           2                   4.8     3.2         5.2
1           3                   5.2     4.8         7.5
1           4                   NaN     5.2         7.5
1           5                   7.5     5.2         NaN
2           1                   1.8     NaN         2.8
2           2                   2.8     1.8         5.4
2           3                   NaN     2.8         5.4
2           4                   5.4     2.8         6.2
2           5                   6.2     5.4         NaN
解决方案

利用Pandas的分组操作和填充功能可以高效实现需求,核心思路是:

  • 由于val在分组内已按升序排列,前序所有行的最大值等价于当前行之前最后一个非NaN值,可通过向前填充(ffill)+移位实现;
  • 后序所有行的最小值等价于当前行之后第一个非NaN值,可通过向后填充(bfill)+移位实现。

具体代码如下:

import pandas as pd

# 构造原始数据
data = {
    'group_id': [1,1,1,1,1,2,2,2,2,2],
    'id_within_group': [1,2,3,4,5,1,2,3,4,5],
    'val': [3.2,4.8,5.2,None,7.5,1.8,2.8,None,5.4,6.2]
}
df = pd.DataFrame(data)

# 分组计算max_prev和min_next
df['max_prev'] = df.groupby('group_id')['val'].apply(lambda x: x.ffill().shift(1))
df['min_next'] = df.groupby('group_id')['val'].apply(lambda x: x.bfill().shift(-1))

print(df)

代码说明

  1. max_prev生成逻辑:
    • 对每个分组的val列执行ffill(),将NaN填充为前面最近的非NaN值;
    • 用shift(1)将结果整体向下移动一行,这样第一行就变为NaN(符合首尾行边界要求),其余行正好是前序所有行的最大值。
  2. min_next生成逻辑:
    • 对每个分组的val列执行bfill(),将NaN填充为后面最近的非NaN值;
    • 用shift(-1)将结果整体向上移动一行,这样最后一行就变为NaN,其余行正好是后序所有行的最小值。

这种方法完全基于Pandas的向量化操作,避免了循环,处理大数据集时效率很高,同时完美适配连续NaN的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 18:40:11