如何在 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)
有一个很好的总结 Dask
和 xarray
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 文件中将固定尺寸尺寸转换为无限制尺寸的主要内容,如果未能解决你的问题,请参考以下文章