繁体   English   中英

python xarray 写入 .netcdf 文件非常慢

[英]python xarray write to netcdf file very slow

for fname in ids['fnames']:
    aq = xr.open_dataset(fname, chunks='auto', mask_and_scale=False)
    aq = aq[var_lists]

    aq = aq.isel(lat=slice(yoff, yoff+ysize), lon=slice(xoff, xoff+xsize))
    list_of_ds.append(aq)
    aq.close()

all_ds = xr.concat(list_of_ds, dim='time')
all_ds.to_netcdf('tmp.nc')

大家好,我正在使用 xarray 读取 .netcdf 文件(大约 1000 个)并将选定的结果保存到一个临时文件中,如上所示。 但是,保存部分运行很慢。 我怎样才能加快速度?

我也试过直接加载数据,但还是很慢。

我也尝试过将open_mfdatasetparallel=True一起使用,而且速度也很慢:

aq = xr.open_mfdataset(
    sorted(ids_list),
    data_vars=var_lists,
    preprocess=add_time_dim,
    combine='by_coords',
    mask_and_scale=False,
    decode_cf=False,
    parallel=True,
)

aq.isel({'lon':irlon,'lat':irlat}).to_netcdf('tmp.nc')

不幸的是,在 xarray 中连接 ~1000 个文件会很慢。 不是解决这个问题的好方法。

如果没有关于您的数据和设置的更多详细信息,我们很难提供具体建议。 但这里有一些我会尝试的事情:

  • 使用xr.open_mfdataset 您的第二个代码块看起来不错。 与使用 for 循环相比,dask 在管理任务方面通常会更快、更有效。
  • 确保您的块与您分割数据的方式保持一致。 您不想阅读更多内容。 如果您正在阅读 .netCDF,您可以灵活地了解如何将数据读入 dask。 由于您正在选择(看起来像)每个数组中的一个小空间区域,因此显式分块数据可能是有意义的,这样您只读取每个数组的一小部分,例如使用chunks={"lat": 50, "lon": 50} . 您需要在这里平衡一些事情 - 确保块大小是可管理的并且不会太小(导致太多任务)。 作为一般规则,拍摄 ~100-500 MB 范围内的块,并尝试将任务数量保持在 100 万以下(或所有数据集中的 # 块小于 ~10-100k)。
  • 明确你的串联。 这个过程感觉越“神奇”,xarray 为推断您的意思所做的工作就越多。 通常, combine='nested''by_coords'执行得更好,因此如果您要连接沿一个或多个维度逻辑结构化的文件,它可能有助于以提供 dim 的相同方式排列文件。
  • 跳过预处理。 如果可以,请在串联时添加新维度,而不是作为摄取步骤。 这允许 dask 更全面地计划计算,而不是将您的预处理 function 视为黑盒,更糟糕的是作为安排最终数组构造操作的先决条件,因为您使用的是combine='by_coords' ,其中坐标是早期 dask 操作的结果。 如果您需要为每个文件附加一个时间维度,每个文件有 1 个元素,例如xr.open_mfdataset(files, concat_dim=pd.Index(pd.date_range("2020-01-01", freq="D", periods=1000), name="time"), combine="nested")根据我的经验,效果很好。

如果这一切花费的时间太长,您可以尝试预处理数据。 使用像nco这样的编译实用程序,或者甚至只是使用dask.distributed的 client.map 对数据进行子集化并将较小的数据子集分组到较大的文件中,可能有助于降低最终数据集连接的复杂性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM