在自己的电脑上处理长时间高分辨率的空间栅格数据时,经常因为数据量过大而导致代码难以运行。在使用python的 xarray包处理分析数据时,可以利用 dask包对较大的数据进行分块并行计算。
使用月均海表温度数据(sst)举个例子
使用dask
需要先安装好 dask 包
import xarray as xr
import dask
import matplotlib.pyplot as plt
## 正常读取数据
data = xr.open_dataset('sst.mnmean.nc')['sst']
## 读取数据并使用 dask中的 chunk方法
data_ch = xr.open_dataset('sst.mnmean.nc',chunks ={'lat':10,'lon':10})['sst']
直接读取的数据
读取的dask arrays数据,可以看到根据chunks参数中给定的字典将数据分为了162个 chunks
如果想将 dask arrays 读为 正常的xarray,使用 load方法, 或者 values方法获取
如果想要改变 chunks 的大小,使用chunk方法即可
data_rechunk = data_ch.chunk({'lat':5,'lon':5})
data_rechunk
可以看到根据重新给定的字典,数据被重新分为了 648 个 chunks
简单的例子
进行一个简单的数据分析来看使用dask的运行效果
求每年的年均sst
## 不使用dask
data_year = data.groupby('time.year').mean()
data_year
## 使用dask
data_ch_year = data_ch.groupby('time.year').mean()
data_ch_year
可以看到不使用dask是需要 896ms,使用时需要 176ms
这只是一个很简单的计算,而且数据量也较小,所以还不能完全体现 dask 的优势,在处理较大的数据,进行更为复杂的计算分析时,效果会更加显著
使用 apply_ufunc
需要将自己定义的沿数据某一维度进行的函数应用到数据上时,需要使用apply_ufunc 函数,对dask array使用时,给定参数 dask=“parallelized”,在数据分析中结合 apply_ufunc 与 dask 能够大大提高数据处理分析的效率
使用ProgressBar进度条
dask 提供了一个进度条工具
将 dask array 的计算分析结果转为 xarray时,常常需要使用 compute 方法
下面以将 dask array 写入 nc 文件为例
from dask.diagnostics import ProgressBar
delayed_obj = data_ch.to_netcdf("data_ch.nc", compute=False)
with ProgressBar():
delayed_obj.compute()