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

如何获取start=True至end=True区间A列最大值并赋值?求更优解法

为expected列赋值符合条件A列值的Pandas优化实现

需求与输入

我们需要根据start和end列的标记,将对应区间内start行的A值,填充到该start之后直到下一个end后续行的expected列。

输入的DataFrame定义如下:

import pandas as pd
import numpy as np
df = pd.DataFrame()
df['A'] = [100, 90, 76, 45, 89, 15, 52, 80, 95, 74]
df['start'] = [False, True, False, False, False, False, True, False, False, False]
df['end'] = [False, False, False, False, True, False, False, False, True, False]

预期输出:

A  start    end  expected
0  100  False  False       NaN
1   90   True  False       NaN
2   76  False  False       NaN
3   45  False  False       NaN
4   89  False   True      90.0
5   15  False  False      90.0
6   52   True  False      90.0
7   80  False  False      90.0
8   95  False   True      80.0
9   74  False  False      80.0

现有实现

你当前的实现思路很巧妙:

g = df.groupby((df['start'] | df['end']).cumsum())
df['expected'] = g['A'].cummax().shift().where(df['end']).ffill()

几种更直观/简洁的替代实现

方法1:基于where+ffill的直观填充

这种方法逻辑清晰,直接定位起始值后填充:

# 仅在start行保留A值,其余为NaN
df['expected'] = df['A'].where(df['start'])
# 向前填充,让后续行继承最近的start值
df['expected'] = df['expected'].ffill()
# 将第一个end之前的未触发填充的行设为NaN
df['expected'] = df['expected'].mask(df['end'].cumsum() == 0)

方法2:分组映射起始值

通过start的累积和分组,直接将每个组的起始值映射到全组:

# 生成分组键:每遇到一个start,分组编号+1
groups = df['start'].cumsum()
# 提取每个分组对应的start行的A值,映射到整个分组
df['expected'] = groups.map(df.loc[df['start'], 'A'].reset_index(drop=True))
# 处理第一个无有效区间的行
df['expected'] = df['expected'].mask(df['end'].cumsum() == 0)

方法3:简化版区间分割填充

利用end标记分割区间,结合ffill实现:

# 先标记出所有需要填充的起始锚点
df['anchor'] = df['A'].where(df['start'])
# 填充锚点到后续区间,直到下一个end后更新
df['expected'] = df['anchor'].ffill()
# 清除第一个end前的无效值
df['expected'] = df['expected'].mask(df['end'].cumsum() == 0)

实现对比

  • 你的原方法利用分组和cummax的组合非常巧妙,但可读性相对弱一些;
  • 方法1和3逻辑直观,代码易读,适合团队协作维护;
  • 方法2的分组映射方式性能优异,适合处理大数据量场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 21:43:34