Python DataFrame滚动窗口下查找大于均值的最小数值及报错解决
问题分析与修复方案
现有问题定位
方法1的局限性
你之前的方法1假设窗口内大于均值的数值固定有5个,所以取第5大的数值,当数据分布变化时结果不符合预期,确实不适用。
方法2的报错&逻辑问题
- 索引越界报错:内层循环
j遍历范围是0~9,当外层循环的i < 10时,i-j会出现负数索引,而pandas的loc不支持负整数取行,因此抛出KeyError: -1 - 列表未重置:
great列表定义在循环体外,每轮循环没有清空,会累计所有历史窗口的数值,最终取到的最小值不属于当前滚动窗口 - 窗口范围不匹配:循环遍历的范围和你计算
avg用的shift+rolling窗口逻辑不一致,会引入不属于当前窗口的数值
最优实现方案
直接在rolling的apply方法中实现逻辑,避免循环索引问题,性能更高,代码如下:
import pandas as pd def min_above_avg(window): window_avg = window.mean() above_avg_vals = window[window > window_avg] # 窗口内无大于均值的数值时返回空值,可根据需求调整默认值 return above_avg_vals.min() if not above_avg_vals.empty else pd.NA # 和你原逻辑对齐:先shift取历史数据,再开10长度的滚动窗口计算 df["test1"] = df["O"].shift().rolling(min_periods=1, window=10).apply(min_above_avg)
如果需要保留循环写法,修改后代码如下:
df['test1'] = pd.NA df["avg"] = df["O"].shift().rolling(min_periods=1, window=10).mean() for i in range(1, len(df)): great = [] # 确定当前窗口的起始索引,避免负索引 window_start = max(0, i - 10) # 遍历当前窗口内的所有历史行 for j in range(window_start, i): if df.loc[j, 'O'] > df.loc[i, 'avg']: great.append(df.loc[j, 'O']) if great: df.loc[i, 'test1'] = min(great)
内容的提问来源于stack exchange,提问作者Deep Vora
相关产品推荐
相关产品推荐

