2017-06-24 30 views
4

在我的实验,到目前为止,我已经试过:xarray或dask是否真的支持内存映射?

  • xr.open_datasetchunks阿根廷,和它的数据加载到内存中。
  • 设置一个NetCDF4DataStore,并调用ds['field'].values并将数据加载到内存中。
  • 设置ScipyDataStoremmap='r',ds['field'].values将数据加载到内存中。

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

我希望能够代表和切片数据为xarray.Dataset,并能够拨打.values(或.data)得到一个ndarray,但它仍然mmapped(共享内存等的目的)。

如果分块的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显然不知道数组是否被映射,并且不能对这些情况强加np.copy

在xarray或dask中是否存在一种“支持”的方式来执行只读的memmapping(或者写入该文件)?

回答

2

xr.open_datasetchunks=不应该立即加载数据到内存中,它应该创建一个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操作可能是懒惰和工作逐块(如果你切,只需要块会被加载)

arr.sum() 

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

arr.sum().values # evaluates 

然而,这不同于内存映射,所以我很感谢如果这不能回答你的问题。

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

+0

我在想如果xarray/dask支持直通式内存映射,它会很酷。但另一方面,大块的延迟加载在功能上几乎是等效的。 我假设xarray默认使用dask.threaded调度程序。 我正在围绕xarray/CF风格的数据模型构建服务器(用于通过websocket访问和查询的Web可视化应用程序),并且试图决定是否依赖上面描述的memmapping hack以及我自己的并行化,而不是在dask上全押。 – chrisbarber

+0

数据本身是只读的,但对于某些查询,可能会基于某些参数/过滤器计算动态掩码数组。这是一个可变的sharedmem数组可能派上用场的地方。虽然使用dask来计算每个请求的掩码也可以。我有更多的调查要靠自己做。我可能会接受你的答案,虽然顺便说一句,因为我的问题似乎是在询问关于xarray的不受支持/未记录的方面,这是一个很高的命令。 – chrisbarber

+0

是的,dask默认使用线程调度器,因此xarray也是这样,除非您创建了分布式客户端。对于HDF文件,这是可取的,因为否则会存在进程间文件锁定问题。对于通过xarray/dask进行大数据集的交互式可视化,您可能希望查看[datashader示例](https://github.com/bokeh/datashader/tree/master/examples)。 – mdurant

相关问题