如何在Pandas中计算Series的滚动半方差与滚动半标准差
Pandas滚动半标准差/半方差实现方案
原代码报错原因
原有代码触发错误的核心原因有两点:
x.rolling(window)返回的是Rolling类型对象,本身不存储具体计算值,不能直接和Series类型的rol_mean做大小比较,会触发类型不匹配错误- Rolling对象不支持直接传入布尔序列做方括号索引,索引操作会触发内部取
columns属性的逻辑,而Series对象没有columns属性,因此报对应属性错误。
向量化实现(性能最优)
核心逻辑:先逐元素过滤掉不符合条件的值(不满足条件的置为NaN),由于Pandas滚动计算默认自动跳过NaN值,直接调用滚动标准差/方差方法即可得到结果,全程用Pandas内置向量化运算,执行效率最高。
完整代码如下:
# 计算标的收益率 x = stock_prices.pct_change() window = 10 # 第一步:计算每个滚动窗口的均值,和原序列索引完全对齐 rol_mean = x.rolling(window=window).mean() # 第二步:过滤序列,仅保留小于对应窗口均值的数值,其余置为NaN x_filtered = x.where(x < rol_mean) # 第三步:对过滤后的序列做滚动计算,自动跳过NaN值 # 滚动半标准差 rol_sem_std = x_filtered.rolling(window=window).std() # 滚动半方差,把std()替换为var()即可 rol_sem_var = x_filtered.rolling(window=window).var()
说明:该方案和原生
rolling().std()的逻辑完全对齐,支持所有原生参数配置,比如要调整标准差自由度、窗口最小有效观测数,直接在std()/var()内传参即可,例如std(ddof=0, min_periods=5)代表计算总体标准差、窗口内至少5个有效值才返回计算结果。
自定义函数实现(适配复杂规则)
如果后续需要更复杂的窗口内筛选逻辑,可以用rolling.apply自定义计算规则,代码可读性更强但性能略低于向量化方案:
import numpy as np def calc_semi_std(window_arr): window_mean = window_arr.mean() # 筛选窗口内小于均值的有效值 valid_vals = window_arr[window_arr < window_mean] # 有效值不足2个时返回NaN(标准差计算至少需要2个样本) if len(valid_vals) < 2: return np.nan return valid_vals.std(ddof=1) rol_sem_std = x.rolling(window=window).apply(calc_semi_std, raw=True)
内容的提问来源于stack exchange,提问作者MedvidekPu
相关产品推荐
相关产品推荐

