如何计算Pandas Series滚动窗口内仅正数的标准差?
问题:计算固定滚动窗口内正数的标准差
我生成了一个取值范围在-1到+1之间的随机Pandas Series:
from pandas import Series from random import random x = Series([random() * 2 - 1. for i in range(1000)])
输出示例:
0 -0.499376 1 -0.386884 2 0.180656 3 0.014022 4 0.409052 ... 995 -0.395711 996 -0.844389 997 -0.508483 998 -0.156028 999 0.002387 Length: 1000, dtype: float64
计算整个序列的滚动标准差很简单:
x.rolling(30).std()
输出示例:
0 NaN 1 NaN 2 NaN 3 NaN 4 NaN ... 995 0.575365 996 0.580220 997 0.580924 998 0.577202 999 0.576759 Length: 1000, dtype: float64
但我的需求是:计算固定滚动窗口(比如大小为30)内仅正数的标准差——如果窗口里只有15个正数,就计算这15个的标准差。
有人尝试先过滤掉负数再计算滚动标准差:
x[x > 0].rolling(30).std()
但这种方法不符合要求:它的窗口是连续的30个正数,而不是原序列中固定长度的窗口内的正数。我想避免遍历整个序列,求更Pythonic的实现方式。
解决方案
方法1:使用rolling.apply(直观但效率较低)
直接对每个滚动窗口筛选正数并计算标准差,当窗口内正数不足2个时返回NaN(标准差至少需要2个样本):
window_size = 30 def positive_std(window): positives = window[window > 0] return positives.std() if len(positives) >= 2 else float('nan') positive_rolling_std = x.rolling(window_size).apply(positive_std, raw=False)
这种方法逻辑直观,但apply本质是逐窗口循环,处理大序列时速度较慢。
方法2:利用滚动统计量推导(高效,适合大规模数据)
利用标准差的数学公式:标准差 = √(均值(平方) - (均值)²),我们可以通过三个滚动统计量推导结果:
window_size = 30 # 仅保留正数,非正数替换为0 x_pos = x.where(x > 0, 0) x_pos_sq = x_pos ** 2 # 计算滚动窗口内正数的数量、总和、平方和 count_pos = x.where(x > 0, 0).rolling(window_size).count() sum_pos = x_pos.rolling(window_size).sum() sum_pos_sq = x_pos_sq.rolling(window_size).sum() # 计算均值与平方均值 mean_pos = sum_pos / count_pos mean_pos_sq = sum_pos_sq / count_pos # 计算标准差,数量不足2时设为NaN positive_rolling_std = (mean_pos_sq - mean_pos ** 2) ** 0.5 positive_rolling_std = positive_rolling_std.where(count_pos >= 2, float('nan'))
这种方法完全依赖Pandas的向量化滚动操作,没有逐窗口循环,效率比apply高得多,适合处理十万级以上的大序列。
内容的提问来源于stack exchange,提问作者dimitriapostol
相关产品推荐
相关产品推荐

