xarray或dask真的支持内存映射吗?

时间:2017-06-24 05:23:43

标签: numpy dask numpy-memmap xarray

到目前为止,在我的实验中,我尝试过:

    带有xr.open_dataset arg的
  • chunks,并将数据加载到内存中。
  • 设置NetCDF4DataStore,然后调用ds['field'].values并将数据加载到内存中。
  • 使用ScipyDataStore设置mmap='r'ds['field'].values将数据加载到内存中。

从我所看到的,设计似乎并不是围绕在内存映射数组上实际应用numpy函数,而是将小块加载到内存中(有时使用内存映射来实现)。例如,this comment。有些相关的评论here关于没有xarray无法确定numpy数组是否被mmapped。

我希望能够将数据表示为xarray.Dataset,并能够调用.values(或.data)来获取ndarray,但是它仍然是mmapped(为了共享内存等目的)。

如果chunked dask操作至少可以在内存映射数组上运行,直到它实际上需要改变一些东西,这似乎是可能的,这似乎是可能的,因为dask似乎是围绕不可变数组设计的。

我确实找到了xarray的技巧,但这样做是这样的:

data=np.load('file.npy', mmap_mode='r')
ds=xr.Dataset({'foo': (['dim1', 'dim2'], data)})

此时,如下所示的工作没有将任何东西加载到内存中:

np.sum(ds['foo'].values)
np.sum(ds['foo'][::2,:].values)

... xarray显然不知道数组是mmapped,并且无法为这类情况强加np.copy

是否有一种“支持”的方式在xarray或dask中进行只读memmapping(或写入此类的写入)?

1 个答案:

答案 0 :(得分:3)

带有xr.open_dataset

chunks=不应该立即将数据加载到内存中,它应该创建一个dask.array,它会懒惰地进行评估。

testfile = '/Users/mdurant/data/smith_sandwell_topo_v8_2.nc'
arr = xr.open_dataset(testfile, chunks={'latitude': 6336//11, 'longitude': 10800//15}).ROSE
arr 

<xarray.DataArray 'ROSE' (latitude: 6336, longitude: 10800)> dask.array</Users/mdurant/data/smith_sandwell_topo_v8_2.nc:/ROSE, shape=(6336, 10800), dtype=float64, chunksize=(576, 720)> Coordinates: * longitude (longitude) float32 0.0166667 0.05 0.0833333 0.116667 0.15 ... * latitude (latitude) float32 -72.0009 -71.9905 -71.9802 -71.9699 ... Attributes: long_name: Topography and Bathymetry ( 8123m -> -10799m) units: meters valid_range: [-32766 32767] unpacked_missing_value: -32767.0 (注意上面的dask.array)

对此的许多xarray操作可能是懒惰的,并且是chunkwise工作(如果你切片,只会加载所需的块)

arr.sum()

<xarray.DataArray 'ROSE' ()> dask.array<sum-aggregate, shape=(), dtype=float64, chunksize=()>

arr.sum().values    # evaluates

这与内存映射不同,所以如果这不能回答你的问题我会很感激。

使用dask的线程调度程序,其他工作人员可以使用内存中的值,因此共享将非常有效。相反,分布式调度程序非常擅长识别何时可以在计算图中或图之间重用结果。