Python 使用map_块在带有xarray的大dask阵列上重新采样和分组?

Python 使用map_块在带有xarray的大dask阵列上重新采样和分组?,python,dask,python-xarray,dask-distributed,Python,Dask,Python Xarray,Dask Distributed,我有一个自定义的工作流,它需要使用重采样来获得更高的时间频率,应用ufunc,和groupby+平均值来计算最终结果 我想将此应用于一个大的xarray数据集,它由一个分块的dask数组支持。对于计算,我想使用dask.distributed 然而,当我将此应用于完整的数据集时,任务的数量猛增,客户机、调度程序和工作人员(如果提交的话)都无法承受 委员会解释说: 尽早进行空间和时间索引(例如.sel()或.isel()) 在管道中,尤其是在调用resample()或groupby()之前。 分组

我有一个自定义的工作流,它需要使用
重采样
来获得更高的时间频率,应用
ufunc
,和
groupby
+
平均值
来计算最终结果

我想将此应用于一个大的
xarray
数据集,它由一个分块的
dask
数组支持。对于计算,我想使用
dask.distributed

然而,当我将此应用于完整的数据集时,任务的数量猛增,客户机、调度程序和工作人员(如果提交的话)都无法承受

委员会解释说:

尽早进行空间和时间索引(例如.sel()或.isel()) 在管道中,尤其是在调用resample()或groupby()之前。 分组和光栅采样在所有块上触发一些计算, 从理论上讲,这应该与索引交换,但是这种优化 尚未在dask中实施

但我真的需要把这个应用到整个时间轴上

那么如何最好地实现这一点呢

我的方法是使用
map_块
,对每个块分别应用此函数,以保持单个
xarray
子数据集足够小

这似乎在小范围内起作用,但当我使用完整的数据集时,工作人员的内存不足,很快就会死亡

查看仪表板,我正在应用于数组的函数执行的块数是我拥有的块数的数倍。这两个号码不是应该排成一行吗

所以我的问题是

  • 这种方法有效吗
  • 除了手动实现
    重采样
    分组比
    部分并将其放入
    ufunc
    中之外,我如何实现此工作流
  • 关于大规模性能问题(特别是执行与块的数量)有什么想法吗
下面是一个模拟工作流的小示例,显示了执行与块的数量:

从时间导入睡眠
进口达斯克
来自dask.distributed import Client,LocalCluster
将numpy作为np导入
作为pd进口熊猫
将xarray作为xr导入
def ufunc(x):
#计算
睡眠(2)
返回x
def fun(x):
#向上采样到更高分辨率
x=x.resample(time=“1h”).asfreq().fillna(0)
#应用函数
x=xr.apply_-ufunc(ufunc,x,输入_-core_-dims=[[“时间”]],输出_-core_-dims=[[“时间”]],dask=“并行化”)
#平均超期
x['time']=x.time.dt.strftime(“%Y-%m-%d”)
x=x.groupby(“时间”).mean()
返回x
def创建(形状):
''helper函数以创建数据集''
x、 y,t=形状
tv=pd.日期\范围(开始=“1970-01-01”,期间=t)
ds=xr.Dataset({
“波段”:xr.DataArray(
dask.array.zero(shape,dtype=“int16”),
dims=['x','y','time'],
coords={“x”:np.arange(0,x),“y”:np.arange(0,y),“time”:tv})
})
返回ds
#设置分布式
集群=本地集群(n_workers=2)
客户端=客户端(群集)
ds=create_xrds((500500)).chunk({“x”:100,“y”:100,“time”:-1})
#创建模板
template=ds.copy()
模板['time']=template.time.dt.strftime(“%Y-%m-%d”)
#将乐趣映射到街区
ds_out=xr.map_块(趣味、ds、模板=模板)
#坚持
d_out.persist()
使用上面的示例,dask数组(25个块)是这样的:

但是函数
fun
执行125次:

查看仪表板,我正在应用于数组的函数执行的块数是我拥有的块数的数倍。这两个号码不是应该排成一行吗

这是误导性的,因为在绘制图表时做出了一个不幸的选择。该数字包括构成输入数据集块的任务(每个块每个变量一个)&对于输出数据集以及应用该函数的任务。这将很快得到修复()