2

当我在 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 时,我将如何应用其他权重?

4

3 回答 3

7

加权滚动均值尚未在 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)

whereconstruct方法构造滚动对象的视图,其中窗口尺寸(window在上面的示例中命名)附加到最后一个位置。与权重数组的内积给出沿窗口维度的加权和。

于 2018-01-30T02:02:59.013 回答
4

如果你想要一个Gaussian-like 过滤器,另一个技巧是递归地应用滚动平均值。

boxcar 滤波器(即我们的滚动平均值)的无限递归变成了高斯滤波器。有关详细信息,请参阅wikipedia 中的 B 样条

例子:

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()

窗口大小为 2 的递归滚动平均值

# 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()

具有集中化窗口大小 3 的递归滚动平均值

注意:如果要集中结果,请使用奇数窗口大小。

于 2018-01-31T23:39:52.620 回答
0

这是特定于 [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.
于 2018-01-30T13:28:02.907 回答