如何在 netcdf 文件中将固定尺寸尺寸转换为无限制尺寸

Posted

技术标签:

【中文标题】如何在 netcdf 文件中将固定尺寸尺寸转换为无限制尺寸【英文标题】:How to convert fixed size dimension to unlimited in a netcdf file 【发布时间】:2015-04-20 07:58: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。 【参考方案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 左右。

【讨论】:

以上是关于如何在 netcdf 文件中将固定尺寸尺寸转换为无限制尺寸的主要内容,如果未能解决你的问题,请参考以下文章

如何在python中将有符号整数转换为无符号整数

如何在 iOS 应用程序中将图像打印到其确切尺寸?

加快在python中读取非常大的netcdf文件

重命名 netCDF 维度

在 python 中将 HEX 转换为无符号 INT16 [重复]

如何在WP8.1 c#中将广告放置在固定位置