带权重的 Xarray 滚动平均值
Xarray rolling mean with weights
当我使用 numpy 中的权重进行 运行 / 滚动平均时,例如做这样的事情:
data = np.random.random(100) # Example data...
weights = np.array([1, 2, 1])
data_m = np.convolve(data, weights/float(np.sum(weights)), "same")
然后将 data_m[0] 和 data_m[-1] 替换为例如nans,取决于应用程序。
xarray 可以完成类似的事情。我所做的(在这种情况下)是
xr.DataArray(data).rolling(dim_0=3, center=True).mean(dim="dim_0")
但是这个对应权重
weights = np.array([1, 1, 1])
在 numpy 示例中。使用 xarray 时,我将如何应用其他权重?
加权滚动均值尚未在 xarray 中实现。
下面的代码做几乎相同的事情,但速度会很慢。
我觉得使用np.convolve是目前最好的选择。
def weighted_sum(x, axis):
weight = [1, 2, 1]
if x.shape[axis] == 3:
return np.sum(x * weight, axis=axis)
else:
return np.nan
da.rolling(dim_0=3, center=True).reduce(weighted_sum)
目前,我们正在努力支持更灵活(和更快)的滚动操作。参见 https://github.com/pydata/xarray/pull/1837
编辑:
xarray=0.10.2,加权滚动平均值计算如下,
weight = xr.DataArray([0.25, 0.5, 0.25], dims=['window'])
da.rolling(dim_0=3, center=True).construct('window').dot(weight)
where construct
方法构造滚动对象的视图,其中 window 维度(在上例中名为 window
)附加到最后一个位置。
权重数组的内积给出 window 维度的加权和。
这是针对 [1,2,1] 权重的,需要两个步骤,所以不是最好的解决方案,但很快:
dim_name = "dim_0"
da_mean = da.rolling(**{dim_name: 3, "center": True}).mean(dim=dim_name)
da_mean = (3 * da_mean + da) / 4. # Expand it, and add the middle value.
如果您想要一个类似于 Gaussian
的过滤器,另一个技巧是递归地应用滚动平均值。
boxcar 滤波器(即我们的滚动均值)的无限递归成为高斯滤波器。
详情请参阅 B-spline in wikipedia。
示例:
x = xr.DataArray([0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], dims=['x'])
# With window=2
tmp = x
plt.plot(tmp, '-ok', label='original')
for i in range(3):
tmp = tmp.rolling(x=2, min_periods=1).mean()
plt.plot(tmp, '-o', label='{}-times'.format(i+1))
plt.legend()
# with window=3, center=True
tmp = x
plt.plot(tmp, '--ok', label='original')
for i in range(3):
tmp = tmp.rolling(x=3, center=True, min_periods=1).mean()
plt.plot(tmp, '-o', label='{}-times'.format(i+1))
plt.legend()
注意:如果要集中结果,请使用奇数 window 大小。
当我使用 numpy 中的权重进行 运行 / 滚动平均时,例如做这样的事情:
data = np.random.random(100) # Example data...
weights = np.array([1, 2, 1])
data_m = np.convolve(data, weights/float(np.sum(weights)), "same")
然后将 data_m[0] 和 data_m[-1] 替换为例如nans,取决于应用程序。
xarray 可以完成类似的事情。我所做的(在这种情况下)是
xr.DataArray(data).rolling(dim_0=3, center=True).mean(dim="dim_0")
但是这个对应权重
weights = np.array([1, 1, 1])
在 numpy 示例中。使用 xarray 时,我将如何应用其他权重?
加权滚动均值尚未在 xarray 中实现。
下面的代码做几乎相同的事情,但速度会很慢。 我觉得使用np.convolve是目前最好的选择。
def weighted_sum(x, axis):
weight = [1, 2, 1]
if x.shape[axis] == 3:
return np.sum(x * weight, axis=axis)
else:
return np.nan
da.rolling(dim_0=3, center=True).reduce(weighted_sum)
目前,我们正在努力支持更灵活(和更快)的滚动操作。参见 https://github.com/pydata/xarray/pull/1837
编辑:
xarray=0.10.2,加权滚动平均值计算如下,
weight = xr.DataArray([0.25, 0.5, 0.25], dims=['window'])
da.rolling(dim_0=3, center=True).construct('window').dot(weight)
where construct
方法构造滚动对象的视图,其中 window 维度(在上例中名为 window
)附加到最后一个位置。
权重数组的内积给出 window 维度的加权和。
这是针对 [1,2,1] 权重的,需要两个步骤,所以不是最好的解决方案,但很快:
dim_name = "dim_0"
da_mean = da.rolling(**{dim_name: 3, "center": True}).mean(dim=dim_name)
da_mean = (3 * da_mean + da) / 4. # Expand it, and add the middle value.
如果您想要一个类似于 Gaussian
的过滤器,另一个技巧是递归地应用滚动平均值。
boxcar 滤波器(即我们的滚动均值)的无限递归成为高斯滤波器。 详情请参阅 B-spline in wikipedia。
示例:
x = xr.DataArray([0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], dims=['x'])
# With window=2
tmp = x
plt.plot(tmp, '-ok', label='original')
for i in range(3):
tmp = tmp.rolling(x=2, min_periods=1).mean()
plt.plot(tmp, '-o', label='{}-times'.format(i+1))
plt.legend()
# with window=3, center=True
tmp = x
plt.plot(tmp, '--ok', label='original')
for i in range(3):
tmp = tmp.rolling(x=3, center=True, min_periods=1).mean()
plt.plot(tmp, '-o', label='{}-times'.format(i+1))
plt.legend()
注意:如果要集中结果,请使用奇数 window 大小。