如何获取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
相关产品推荐
相关产品推荐

