python - Python:如何使用 xarray 编写大型 netcdf
问题描述
我正在使用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:
# https://stackoverflow.com/a/65416801/9940782
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)
返回一个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,我会检查该格式!
推荐阅读
- c# - 如何在 asp.net core 中创建端点,接受多个文件,每个文件都有一个链接的文本?
- java - 如果 Maven 依赖关系传递地冲突,是否可以在调解期间将其标记为“低优先级”?
- laravel - Laravel 查询未获取所有值(无法获取空值)
- node.js - NodeJs 的高级日志记录:TypeError: X is not iterable
- javascript - 使用 Jquery Ajax 在 Spring MVC 控制器中传递字符串列表
- python - 将 Python UDF 应用于 Spark 数据帧时出现 java.lang.IllegalArgumentException
- json - 如果它不存在,如何有条件地将密钥添加到json?
- matlab - 在 Matlab 中绘制力
- python - Pandas read_pickle() 函数返回 NaN 值
- reactjs - 如何设置作为道具传递的材质 UI 图标