我有一个非常大的netcdf数据集,由1985年4月到2024年4月的每日块数据组成。由于数组被分为每日块,我经常使用
ds = xr.open_mfdataset(*.nc)
打开它们。整个数据集高达 1.07TB,这远远超出了我可以处理加载到内存中的能力:
通过对纬度/经度坐标进行切片
ds.sel(latitude=y, longitude=x, method='nearest')
我沿着时间序列得到了一个像素,它现在比原始数据集轻得多,并允许我执行我需要的分析:
但是,尽管切片数据集现在非常轻,但仍然需要很长时间才能将其加载到内存中(超过 1 小时)
ds.load()
。如果我不需要执行此操作超过 100,000 次(这将需要令人难以置信的 10 年才能完成),那么这并不是什么大问题!
我没有强大的机器,但它足以执行我需要的任务。虽然我预计这项任务需要一些时间,但我真的希望在成为父亲之前完成它。除了购买更强大的机器(我认为这仍然不会将所需时间减少到天量级)之外,还有什么方法可以尝试优化此任务?
问题是切片结果仍然需要很多操作。在您分享的屏幕截图上,“Dask graph”字段仍然有大量的层和块。
可能的前进方向包括:
chunks
kwarg 选择最合适的分块。粗略猜测:import dask
import xarray as xr
ds = xr.open_mfdataset(*.nc, chunks={"time": 15_000})
slice = ds.sel(latitude=y, longitude=x, method='nearest')
slice.compute()
支付时间/磁盘空间方面的固定成本,并将数据重塑为与您的工作流程最兼容的格式/块;
尝试
dask.optimize
,粗略的伪代码:
import dask
import xarray as xr
ds = xr.open_mfdataset(*.nc)
slice = ds.sel(latitude=y, longitude=x, method='nearest')
(optimized_slice,) = dask.optimize(slice)
optimized_slice.compute()