使用netcdf文件中的dask.array时,scheduler =“ processes”的变量不可选错误

时间:2019-04-03 09:38:20

标签: python dask netcdf

我正在尝试使用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。

1 个答案:

答案 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。