首次执行时从 NetCDF 文件中获取特定单元格值很慢
Getting specific cell value from NetCDF file slow on first execution
我正在使用 xarray python 库访问 netcdf 文件。我正在使用的特定文件是公开的 available.
所以,文件有几个变量,对于这些变量中的大多数,维度是:时间:4314,x:700,y:562。我正在使用 ET_500m 变量,但行为是其他变量也类似。分块为:288、36、44。
我正在检索单个单元格并使用以下代码打印值:
import xarray as xr
ds = xr.open_dataset('./dataset_greece.nc')
print(ds.ET_500m.values[0][0][0])
按照我的理解,xarray应该直接定位到磁盘中包含相应值的chunk的位置,然后读取。由于块的大小不应超过几 MB,我希望这需要几秒钟甚至更短的时间。但相反,它需要超过 2 分钟。
如果在同一个脚本中检索另一个单元格的值,即使它位于不同的块中(例如 print(ds.ET_500m.values[1000][500][500])
),那么第二次检索只需要几毫秒。
所以我的问题是,在第一次检索中究竟是什么导致了这种开销?
编辑:我刚刚看到在 xarray open_dataset 中有可选参数缓存,根据 manual:
If True, cache data loaded from the underlying datastore in memory as NumPy arrays when accessed to avoid reading from the underlying data- store multiple times. Defaults to True [...]
所以,当我将其设置为 False 时,后续的提取也像第一次一样慢。但我的问题仍然存在。为什么这么慢,因为我只访问一个单元格。我期待 xarray 直接在磁盘上定位块并且只读取几 MB。
与其从 .values
属性 中选择,不如首先对数组进行子集化:
print(ds.ET_500m[0, 0, 0].values)
问题是 .values
将数据强制转换为 numpy 数组,因此您要加载所有数据,然后对数组进行子集化。 xarray 没有办法解决这个问题 - numpy 没有任何延迟加载的概念,所以一旦你调用 .values
xarray 别无选择,只能加载(或计算)你的所有数据。
如果数据是 dask-backed 数组,您可以使用 .data
而不是 .values
来访问 dask 数组并在 dask 数组上使用位置索引,例如ds.ET_500m.data[0, 0, 0]
。但是如果数据只是一个 lazy-loaded netCDF .data
将具有与上述相同的 load-everything 陷阱。
我正在使用 xarray python 库访问 netcdf 文件。我正在使用的特定文件是公开的 available.
所以,文件有几个变量,对于这些变量中的大多数,维度是:时间:4314,x:700,y:562。我正在使用 ET_500m 变量,但行为是其他变量也类似。分块为:288、36、44。
我正在检索单个单元格并使用以下代码打印值:
import xarray as xr
ds = xr.open_dataset('./dataset_greece.nc')
print(ds.ET_500m.values[0][0][0])
按照我的理解,xarray应该直接定位到磁盘中包含相应值的chunk的位置,然后读取。由于块的大小不应超过几 MB,我希望这需要几秒钟甚至更短的时间。但相反,它需要超过 2 分钟。
如果在同一个脚本中检索另一个单元格的值,即使它位于不同的块中(例如 print(ds.ET_500m.values[1000][500][500])
),那么第二次检索只需要几毫秒。
所以我的问题是,在第一次检索中究竟是什么导致了这种开销?
编辑:我刚刚看到在 xarray open_dataset 中有可选参数缓存,根据 manual:
If True, cache data loaded from the underlying datastore in memory as NumPy arrays when accessed to avoid reading from the underlying data- store multiple times. Defaults to True [...]
所以,当我将其设置为 False 时,后续的提取也像第一次一样慢。但我的问题仍然存在。为什么这么慢,因为我只访问一个单元格。我期待 xarray 直接在磁盘上定位块并且只读取几 MB。
与其从 .values
属性 中选择,不如首先对数组进行子集化:
print(ds.ET_500m[0, 0, 0].values)
问题是 .values
将数据强制转换为 numpy 数组,因此您要加载所有数据,然后对数组进行子集化。 xarray 没有办法解决这个问题 - numpy 没有任何延迟加载的概念,所以一旦你调用 .values
xarray 别无选择,只能加载(或计算)你的所有数据。
如果数据是 dask-backed 数组,您可以使用 .data
而不是 .values
来访问 dask 数组并在 dask 数组上使用位置索引,例如ds.ET_500m.data[0, 0, 0]
。但是如果数据只是一个 lazy-loaded netCDF .data
将具有与上述相同的 load-everything 陷阱。