沿着XArray的时间维度应用函数

6
我有一个图像堆栈,存储在XArray DataArray中,具有时间、x、y三个维度。我想在每个像素的时间轴上应用自定义函数,以便输出是一个x、y两个维度的单个图像。
我尝试了apply_ufunc,但它失败了,并指出我需要首先将数据加载到RAM中(即不能使用Dask Array)。理想情况下,我希望在内部将DataArray保持为Dask Arrays,因为无法将整个堆栈加载到RAM中。确切的错误消息如下:
ValueError: apply_ufunc遇到了一个参数的dask数组,但处理dask数组的操作尚未启用。请设置“dask”参数或使用.load()或.compute()将数据首先加载到内存中。
我的代码目前看起来像这样:
import numpy as np
import xarray as xr
import pandas as pd 

def special_mean(x, drop_min=False):
    s = np.sum(x)
    n = len(x)
    if drop_min:
    s = s - x.min()
    n -= 1
    return s/n

times = pd.date_range('2019-01-01', '2019-01-10', name='time')

data = xr.DataArray(np.random.rand(10, 8, 8), dims=["time", "y", "x"], coords={'time': times})
data = data.chunk({'time':10, 'x':1, 'y':1})

res = xr.apply_ufunc(special_mean, data, input_core_dims=[["time"]], kwargs={'drop_min': True})

如果我使用.compute将数据加载到RAM中,仍然会出现错误,该错误显示:

ValueError: 应用的函数返回了意外维度数量的数据:0与2相对于维度('y','x')

我不确定我缺少/做错了什么。


apply_ufunc 仍然是最佳选择。你能提供一下你尝试过的例子吗?提供一个 MCVE(https://stackoverflow.com/help/minimal-reproducible-example)有助于回答你的问题。 - jhamman
我已更新问题,包括MCVE和确切的错误。 - System123
3个回答

7
def special_mean(x, drop_min=False):
    s = np.sum(x)
    n = len(x)
    if drop_min:
        s = s - x.min()
    n -= 1
    return s/n

times = pd.date_range('2019-01-01', '2019-01-10', name='time')

data = xr.DataArray(np.random.rand(10, 8, 8), dims=["time", "y", "x"], coords={'time': times})
data = data.chunk({'time':10, 'x':1, 'y':1})

res = xr.apply_ufunc(special_mean, data, input_core_dims=[["time"]], kwargs={'drop_min': True}, dask = 'allowed', vectorize = True)

使用上面的代码并使用 vectorize 参数应该可以工作。


请您在调整时提供一些说明 - Hugo Roussaffa
1
ValueError: applied function returned data with unexpected number of dimensions. Received 0 dimension(s) but expected 2 dimensions with names: ('y', 'x') - upuil

0

我的目标还包括实现来自 Xarray 的 apply_ufunc,以便它可以计算沿 x 和 y 的特殊均值。

我喜欢 Ales 的例子;当然需要省略与 chunk 相关的那一行代码。否则:

ValueError: applied function returned data with unexpected number of dimensions. Received 0 dimension(s) but expected 2 dimensions with names: ('y', 'x')

0
有趣的是,我意识到,在某些情况下,为了使apply_ufunc的输出变成3D而不是2D,我们需要在apply_ufunc中添加"out_core_dims=[["time"]]"。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接