Python: 如何用 xarray 编写大型 netcdf

Python: How to write large netcdf with xarray

我正在使用 xr.mfdataset 加载以下数据。有 16GB 的数据,跨越许多文件。

import xarray as xr
from datetime import datetime
from pathlib import Path

from dask.diagnostics import ProgressBar
def add_time_dim(xda: xr.Dataset) -> xr.Dataset:
    #  
    xda = xda.expand_dims(time = [datetime.now()])
    return xda

raw_folder = data_dir / "raw/modis_ndvi_1000"
    
files = [f for f in raw_folder.glob("*.nc")]
data = xr.open_mfdataset(files, preprocess=add_time_dim)
data
<xarray.Dataset>
Dimensions:     (time: 647, lat: 5600, lon: 4480)
Coordinates:
  * time        (time) datetime64[ns] 2004-04-30 2005-10-10 ... 2018-10-31
  * lat         (lat) float64 -19.99 -19.98 -19.97 -19.96 ... 29.98 29.99 30.0
  * lon         (lon) float64 20.0 20.01 20.02 20.03 ... 59.96 59.97 59.98 59.99
Data variables:
    modis_ndvi  (time, lat, lon) float32 dask.array<chunksize=(1, 5600, 4480), meta=np.ndarray>

选择我感兴趣的区域后,我将数据集的大小减半 (~8GB)

<xarray.Dataset>
Dimensions:     (time: 647, lat: 1255, lon: 983)
Coordinates:
  * time        (time) datetime64[ns] 2004-04-30 2005-10-10 ... 2018-10-31
  * lat         (lat) float64 -5.196 -5.187 -5.179 -5.17 ... 5.982 5.991 6.0
  * lon         (lon) float64 33.51 33.52 33.53 33.54 ... 42.26 42.27 42.28
Data variables:
    modis_ndvi  (time, lat, lon) float32 dask.array<chunksize=(1, 1255, 983), meta=np.ndarray>

## 每次尝试保存数据,过程都是Killed。如何将这个大文件写入 netcdf?

out_folder = data_dir / "interim/modis_ndvi_1000_preprocessed"
out_folder.mkdir(exist_ok=True)
out_file = out_folder / f"modis_ndvi_1000_{subset_str}.nc"

data.to_netcdf(out_file, compute=False)
with ProgressBar():
    print(f"Writing to {out_file}")
    data.compute()


Killed

我需要做什么?如何处理这个大数据集,如何将它并行写入磁盘?

进程被杀死,因为所有可用内存都用完了(观看时可以看到htop

to_netcdf(compute=False) returns 一个 dask.delayed.Delayed 对象。您应该将其存储为变量并计算它而不是计算数组:

write_job = data.to_netcdf(out_file, compute=False)
with ProgressBar():
    print(f"Writing to {out_file}")
    write_job.compute()

您拥有的代码会启动延迟写入作业,然后尝试将整个数组 data 放入内存。

也就是说,zarr 更适合并行写入。即使数组支持分布式任务集群,to_netcdf 也会将数组带到本地线程(以块的形式,但仍然)写入主线程中的 netcdf。用 zarr 写入调度写入,然后工作人员并行写入存储。如果您在网络或云文件系统上,这可能会产生巨大的差异。如果您能够使用 zarr,我会查看该格式!