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,我会查看该格式!
我正在使用 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,我会查看该格式!