如何计算360度圆周角度序列的循环移动平均(解决pandas滚动均值边界问题)
圆周循环序列的固定窗口移动平均实现方案
pandas默认的rolling方法不支持圆周边界的循环衔接,前window-1个位置因为窗口凑不齐返回NaN,会直接丢失头尾衔接部分的平滑结果,对应你提到的0-9度的计算需求。
两种可直接落地的实现方法
方法1:首尾缓冲区拼接(兼容性最好)
核心思路是为了计算头部位置的循环窗口,提前在原序列最前面拼接一段末尾的观测值当缓冲区,用普通滚动计算后裁掉缓冲区的多余结果,就能和原序列完全对齐:
import pandas as pd window = 10 # 和你当前使用的计算窗口大小保持一致 # 取原序列最后window-1个值作为缓冲区,拼到序列最前面 padded_series = pd.concat([ df['value'].tail(window - 1), df['value'] ]) # 在拼接后的完整序列上做固定窗口的普通滚动平均 rolling_result = padded_series.rolling(window=window).mean() # 裁掉缓冲区对应的前window-1个结果,和原DataFrame长度对齐 df['smoothed'] = rolling_result.iloc[window - 1:].values
- 逻辑匹配说明:计算0度的平滑值时,窗口刚好覆盖拼接段末尾的351-359度、加上原序列0度的观测值,凑够10个值求平均;计算1度的平滑值时,窗口覆盖352-359度、加上原序列0-1度的观测值,完全匹配你期望的计算规则,全程不会出现NaN。
方法2:循环卷积(计算效率更高)
对于固定长度的圆周序列,可以直接用numpy的卷积接口实现循环边界的等权平均,不需要手动拼接序列:
import numpy as np window = 10 # 构造等权平均的卷积核 mean_kernel = np.ones(window) / window # 用wrap模式做循环卷积,自动处理头尾衔接,输出和原序列等长 df['smoothed'] = np.convolve(df['value'].to_numpy(), mean_kernel, mode='wrap')
- 说明:
mode='wrap'模式天生适配圆周循环场景,计算窗口在到达序列头部边界时,会自动从序列末尾补全窗口需要的数值,不需要额外做边界判断。
校验提示:你可以手动取一组边界值核对结果,比如0度位置的平滑值,手动计算351到0度共10个值的算术平均,和代码输出的结果完全一致;359度位置的平滑值和普通rolling计算的结果完全相同,不存在错位。
- 注意避坑:不要通过设置
rolling(min_periods=1)来补前几个位置的NaN,这种方式计算前几个值的窗口长度不足,均值的分母和你要求的固定10窗口不一致,不符合圆周循环的计算规则。
内容的提问来源于stack exchange,提问作者Igor K.
相关产品推荐
相关产品推荐

