如何在Pandas DataFrame中为动态窗口计算最大值及其下方最小值?
Pandas动态窗口计算a_max和a_min列实现方案
问题描述
现有如下Pandas DataFrame:
import pandas as pd df = pd.DataFrame( { 'a': [3, 1, 2, 5, 10, 3, 13, 3, 2], } )
需要生成a_max和a_min列,预期输出如下:
a a_max a_min 0 3 NaN NaN 1 1 3.0 1.0 2 2 3.0 1.0 3 5 3.0 1.0 4 10 3.0 1.0 5 3 10.0 3.0 6 13 10.0 3.0 7 3 13.0 3.0 8 2 13.0 2.0
逻辑规则:
- 动态窗口逐行扩展,第n个窗口包含前n行数据
- 对每个窗口,先找到最大值,再找出该最大值位置之后窗口内的最小值
- 若最大值位于窗口末尾(当前行即为最大值,窗口内无后续数据),则沿用前一行的
a_max和a_min值
尝试cummax和cummin方法无法得到预期结果,需正确实现方案。
解决方案
通过逐行遍历并维护窗口关键信息的方式实现,代码如下:
import pandas as pd df = pd.DataFrame({'a': [3, 1, 2, 5, 10, 3, 13, 3, 2]}) # 初始化结果列 df['a_max'] = pd.NA df['a_min'] = pd.NA # 维护窗口状态变量 current_max = None max_index = -1 post_max_min = None for idx in range(1, len(df)): # 提取当前窗口(前idx+1行) window = df['a'].iloc[:idx+1] window_max = window.max() window_max_idx = window.idxmax() # 窗口最大值未发生变化(值和位置都不变),沿用前一行结果 if window_max == current_max and window_max_idx == max_index: df.loc[idx, 'a_max'] = df.loc[idx-1, 'a_max'] df.loc[idx, 'a_min'] = df.loc[idx-1, 'a_min'] else: # 更新最大值及索引 current_max = window_max max_index = window_max_idx # 最大值不在窗口末尾,计算后续最小值 if max_index < idx: post_max_min = window.iloc[max_index+1:].min() df.loc[idx, 'a_max'] = current_max df.loc[idx, 'a_min'] = post_max_min else: # 最大值在窗口末尾,沿用前一行结果(排除第二行的特殊情况) if idx > 1: df.loc[idx, 'a_max'] = df.loc[idx-1, 'a_max'] df.loc[idx, 'a_min'] = df.loc[idx-1, 'a_min'] # 转换数据类型匹配预期输出格式 df['a_max'] = df['a_max'].astype(float) df['a_min'] = df['a_min'].astype(float) print(df.to_string(index=False))
代码说明
- 初始化:创建结果列并设为缺失值,同时定义变量跟踪当前窗口的最大值、最大值索引、最大值后的最小值。
- 逐行处理:从第二行开始遍历,因为第一行无前置数据,保持缺失值。
- 窗口逻辑判断:
- 若窗口最大值的数值和位置都未改变,直接复用前一行的结果,避免重复计算。
- 若最大值更新,重新计算最大值位置之后的窗口最小值并赋值。
- 若最大值位于当前窗口末尾,复用前一行的结果。
运行上述代码即可得到符合预期的输出。
内容的提问来源于stack exchange,提问作者AmirX
相关产品推荐
相关产品推荐

