使用加权平均值粗化 xarray DataArray

Coarsen xarray DataArray with weighted mean

假设我有一些 DataArray:

da = xr.DataArray(
    data=np.random.random((25,25)),
    dims=["x", "y"],
    coords=dict(
        x=np.arange(25),
        y=np.arange(25),
    ),
)

我想将这个数组下采样到 5x5 块。我可以使用粗化函数来做到这一点:

da_coarse = da.coarsen(x=5,y=5).mean()

据我了解,这基本上是将 DataArray 拆分为 5x5“块”并将每个块平均为一个值。然而,我想做的是取这个 5x5 组的加权平均值,所以中心点在最终平均值中的权重比边缘点更大。

我可以创建一个具有如下权重的高斯内核:

def gkern(kernlen=21, sig=3):
    import scipy.stats as st
    
    """Returns a 2D Gaussian kernel."""
    x = np.linspace(-(kernlen/2)/sig, (kernlen/2)/sig, kernlen+1)
    kern1d = np.diff(st.norm.cdf(x))
    kern2d = np.outer(kern1d, kern1d)
    return kern2d/kern2d.sum()

window = gkern(5)

其中 window 现在是一个 5x5 数组,每个点都具有所需的权重。但是,我不确定如何在粗化函数中进行平均时实现此 window/kernel。

最好的方法是什么?

一种方法是通过 DataArrayCoarsen.construct,这样您可以更轻松地一次对单个 windows 进行操作:

weights = xr.DataArray(gkern(5), dims=["x_window", "y_window"])
windowed_da = da.coarsen(x=5, y=5).construct(
    x=("x_coarse", "x_window"),
    y=("y_coarse", "y_window")
)
coarsened = (weights * windowed_da).sum(["x_window", "y_window"]) / weights.sum()

windowed_da 是原始 DataArray,但已重塑为 coarsen 步骤中指定大小的单个 windows。