【问题标题】:How to convert fixed size dimension to unlimited in a netcdf file如何在 netcdf 文件中将固定尺寸尺寸转换为无限制尺寸
【发布时间】:2023-04-11 06:37:01
【问题描述】:

我每天下载 600MB netcdf-4 具有这种结构的文件:

netcdf 我的文件 { 方面: time_counter = 18 ; 深度 = 50 ; 纬度 = 361 ; 经度 = 601 ; 变量: 盐度 温度等

我正在寻找一种更好的方法将 time_counter 维度从固定大小 (18) 转换为无限维度。

我找到了一种使用 netcdf 命令和 sed 的方法。像这样:

ncdump myfile.nc | sed -e "s#^.time_counter = 18 ;#time_counter = UNLIMITED ; // (当前为 18)#" | ncgen -o myfileunlimited.nc

这对我来说适用于小文件,但是在转储 600 MB netcdf 文件时,会占用大量内存和时间。

有人知道完成此任务的另一种方法吗?

【问题讨论】:

  • 对于你正在做的替换,sed 和管道链的效率差不多。除非您使用hadoop 类型的解决方案,否则会将文件分成几部分,将这些部分发送到多个服务器,执行操作,然后将文件“粘合”在一起。我看不出内存如何成为问题,sed 一次处理一行。我对nc 工具套件一无所知,所以也许有一些选项可以让ncgen 更有效地运行? (可能不是)您的计算机是否适合此任务?是时候让老板买新的了!是的!!祝你好运!
  • 多少时间和内存是“太多”?如果内存使用呈线性增长,我认为您不需要超过几十 GB。

标签: linux sed netcdf nco


【解决方案1】:

您可以使用xarray python 包的xr.to_netdf() 方法,然后通过使用Dask 优化内存使用。

您只需要传递维度的名称以使unlimited_dims 参数不受限制,并使用chunks 来拆分数据。例如:

import xarray as xr
ds = xr.open_dataset('myfile.nc', chunks={'time_counter': 18})
ds.to_netcdf('myfileunlimited.nc', unlimited_dims={'time_counter':True})

有一个很好的总结 Daskxarray linked here

【讨论】:

    【解决方案2】:

    您的回答很有见地。我并不是真的在寻找改进这种 ncdump-sed-ncgen 方法的方法,我知道转储 600MB 的 netcdf 文件在文本文件(CDL 表示)中使用了几乎 5 倍的空间。然后修改一些标题文本并再次生成netcdf文件,感觉不是很有效。

    我阅读了最新的 NCO 命令文档,发现了一个特定于 ncks 的选项“--mk_rec_dmn”。 Ncks主要提取和写入或附加数据到一个新的netcdf文件,那么这似乎是更好的方法,提取myfile.nc的所有数据并用“--mk_rec_dmn”所做的新记录维度(无限维度)写入它,然后替换旧文件。

    ncks --mk_rec_dmn time_counter myfile.nc -o myfileunlimited.nc ; mv myfileunlimited.nc myfile.nc

    做相反的操作(记录维度到固定大小)会是。

    ncks --fix_rec_dmn time_counter myfile.nc -o myfilefixedsize.nc ; mv myfilefixedsize.nc myfile.nc

    【讨论】:

    • 如果网站回答了问题,则接受您自己的答案是可以接受的。很好的发现。
    • Favo,您找到了正确的方法。与 sed 方法相比,使用 NCO 可以大大减少内存消耗。一次只有一个变量保存在内存中。 ncdump/sed 方法无法扩展。加上 NCO 在“历史”属性中记录元数据的变化,让下游用户知道你做了什么。
    • 你不需要-o myfileunlimited.nc ; mv myfileunlimited.nc myfile.nc,只要说-O -o myfile.nc(-O是可选的,用于覆盖原始文件而不询问)。
    【解决方案3】:

    shell 管道只能通过使 sed 步骤仅修改文件的开头并传递所有其他内容来略微改进,但是您拥有的表达式处理起来非常便宜,并且不会减少花费的时间。

    核心问题很可能是您在ncdump 将文件信息格式化为文本数据以及在ncgen 再次将文本数据解析为NetCDF 文件格式方面花费了大量时间。

    由于通过 dump+gen 的路径与显示的一样慢,因此使用 NetCDF 功能来转换您的数据文件。

    如果幸运的话,可能会有一些工具直接对您的数据文件进行操作以进行更改或转换。如果没有,您可能必须使用 NetCDF 库自己编写它们。

    如果您非常不走运,NetCDF-4 文件是带有一些额外元数据的 HDF5 文件。特别是,维度的长度存储在_netCDF 组中的_netcdf_dim_info 数据集中(或者documentation 告诉我)。

    可以修改那里的信息以将time_counter 维度的当前长度转换为 UNLIMITED 的值(即数字 0),但如果您这样做,您真的 需要验证生成的文件的完整性,正如文档整齐地指出的那样:

    “请注意,使用 HDF5 修改这些文件几乎肯定会使它们对 netCDF-4 不可读。”

    附带说明,如果此过程对您的团队很重要,那么可能值得研究哪些硬件可以更快地完成任务。在我的 Bulldozer 系统上,转换 78 MB 文件的过程需要 20 秒,使用大约 500 MB 内存用于 ncgen 工作集(1 GB 虚拟)和 12 MB 内存用于 ncdump 工作集(111 MB 虚拟),每个任务占用更好的核心部分。

    任何像样的磁盘都应该在 10 秒左右读取/接收您的文件,只要您不交换内存,内存就无关紧要,因此如果您采用转储+生成路线,CPU 可能是您最关心的问题。

    如果并发内存使用是一个大问题,您可以通过将 sed 的中间结果保存到磁盘来交换一些字节以换取空间,这可能需要多达 1.5 GB 左右。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-25
      • 2018-05-18
      • 1970-01-01
      • 2020-10-30
      • 2020-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多