如何在Pandas中计算多列滚动标准差(忽略NaN、窗口3、最小周期2)
解决多列滚动标准差(忽略NaN)的问题
原始数据
import pandas as pd import numpy as np data = {'a': {1: None, 2: 1, 3: 7, 4: 2, 5: 4}, 'b': {1: None, 2: 2, 3: 2, 4: 9, 5: 6}, 'c': {1: None, 2: 2.0, 3: None, 4: 7.0, 5: 4.0}} df = pd.DataFrame(data).rename_axis('day')
输出:
a b c day 1 NaN NaN NaN 2 1.0 2.0 2.0 3 7.0 2.0 NaN 4 2.0 9.0 7.0 5 4.0 6.0 4.0
需求说明
新增一列std,计算规则:
- 滚动窗口行数为3
- 计算窗口内所有列的非NaN值的标准差(自由度
ddof=1,与np.std(..., ddof=1)结果一致) - 仅当窗口内非NaN值数量≥2时计算,否则返回NaN(对应
min_periods=2的要求)
预期输出
a b c std day 1 NaN NaN NaN NaN 2 1.0 2.0 2.0 NaN 3 7.0 2.0 NaN 2.387467 4 2.0 9.0 7.0 3.116775 5 4.0 6.0 4.0 2.531939
注:第3行的std值等于np.std([1,2,2,7,2], ddof=1)的计算结果。
解决方案
直接使用pandas内置滚动方法无法满足跨列合并非NaN值的需求,可自定义滚动函数实现:
def rolling_std(window): # 将窗口内的多列数据转为一维数组,过滤空值 valid_vals = window.stack().dropna().values # 检查有效数据量是否达标 return np.std(valid_vals, ddof=1) if len(valid_vals) >= 2 else np.nan # 应用滚动窗口计算 df['std'] = df.rolling(window=3, min_periods=2).apply(rolling_std, raw=False)
代码说明
rolling(window=3, min_periods=2):设置滚动窗口大小为3行,且窗口至少包含2行数据才触发计算apply(rolling_std, raw=False):raw=False确保传入函数的是DataFrame格式的窗口数据,方便后续跨列处理- 函数内通过
stack()将窗口的行列结构转为一维,dropna()过滤空值后,用np.std计算样本标准差(ddof=1)
内容的提问来源于stack exchange,提问作者younggotti
相关产品推荐
相关产品推荐

