我正在尝试使用dask处理3维数组(x,y,时间)。这些数组存储为netcdf4文件,并已使用netCDF4 python库编写。我可以从netcdf文件中定义的变量创建dask.array,当我尝试使用scheduler =“ processes”计算结果时,会引发以下错误:
NotImplementedError: Variable is not picklable
我知道parallel writing is not supported when using dask with netcdf,但是在沿时间轴的均值的简单计算过程中会引起误差。 This post似乎相关,但无助于解决我的问题。沿时间轴计算平均值仅用于演示目的。在实践中,我将应用更复杂的功能,这些功能仅部分基于numpy,这就是为什么我想通过使用dask中的进程来回避Python的Global Interpreter Lock。
import dask.array as da
import netCDF4
path = 'path/to/netcdf_file'
dset = netCDF4.Dataset(path, 'r')
var = dset['var']
x = da.from_array(var, chunks=(500, 500, 2))
dset.close()
result = da.mean(x, axis=2)
# raises NotImplementedError: Variable is not picklable
result.compute(scheduler="processes")
# works just fine
result.compute(scheduler="threads")
.compute(scheduler="processes")
为什么会引发错误,可能的解决方法是什么?由于我有许多netcdf4格式的文件,因此我希望避免将所有内容都转换为另一种文件格式。
我正在CentOS 7上运行Python 2.7(miniconda发行版)。已经从conda-forge安装了Dask v1.1.4和netCDF4 v1.4.3.2。
答案 0 :(得分:1)
在使用Dask的多处理调度程序(例如scheduler="processes"
)时,进程将需要分别处理打开和访问netCDF数据。我强烈建议尝试将Xarray用于此任务,因为它内置了对与netCDF和Dask一起使用的支持。我在下面使用Xarray / Dask / netCDF4编写了等效的工作流程:
import dask
import xarray as xr
ds = xr.open_dataset('path/to/netcdf_file',
engine='netcdf4',
chunks={'x': 500, 'y': 500, 'z': 2})
with dask.config.set(scheduler='processes'):
result = ds['var'].mean(dim='z').load()
Xarray's documentation上有一个不错的页面,讨论如何在这种情况下使用dask。