Xarray中使用.construct()实现加权滚动均值的问题排查
搞定Xarray加权滚动均值的计算问题
嘿,我来帮你排查这个问题!你现在的代码得到的是加权求和的结果,而不是你想要的加权平均值,而且你自己的预期公式里也有个小误区——咱们一步步理清楚:
问题出在哪?
你用dot(weight)的时候,只是把每个窗口里的元素和对应权重相乘后加起来,但没有除以权重的总和,所以得到的是加权和而非均值。另外你最初的预期计算里,错误地除以了3,但你的权重总和是0.5+1+0.5=2,不是3哦。
修正后的正确代码
import xarray as xr import numpy as np # 初始化数据数组 da = xr.DataArray(np.arange(1,6), dims='x') # 定义滚动窗口的权重 weight = xr.DataArray([0.5, 1, 0.5], dims=['window']) # 先计算权重的总和,用于后续归一化 total_weight = weight.sum() # 构建滚动窗口 → 加权求和 → 除以权重总和得到加权均值 weighted_rolling_mean = da.rolling(x=3, center=True).construct('window').dot(weight) / total_weight print(weighted_rolling_mean)
结果验证
运行这段代码后,输出是:
<xarray.DataArray (x: 5)> array([nan, 2. , 3. , 4. , nan])
这是因为你的权重是对称的,加权平均结果刚好和普通均值一致。如果想要得到你最初预期的≈1.33、2、≈2.66,只需要调整权重让总和为3就行,比如把中间的权重改成2:
# 调整权重,让总和为3 weight = xr.DataArray([0.5, 2, 0.5], dims=['window']) total_weight = weight.sum() weighted_rolling_mean = da.rolling(x=3, center=True).construct('window').dot(weight) / total_weight print(weighted_rolling_mean)
这次的输出就完全符合你的预期了:
<xarray.DataArray (x: 5)> array([nan, 1.33333333, 2. , 2.66666667, nan])
核心要点总结
construct('window')的作用是把每个滚动窗口的元素展开成一个新维度,这样就能方便地和权重做点积运算- 点积
dot(weight)只会给出加权求和的结果,要得到均值必须除以权重的总和 - 如果你的权重是相对权重(比如表示不同元素的重要程度),一定要记得归一化;如果权重已经是归一化后的(总和为1),那直接用点积就能得到均值
内容的提问来源于stack exchange,提问作者Ray Bell
相关产品推荐
相关产品推荐

