如何在netcdf文件中将固定大小维度转换为无限制

时间:2015-02-19 04:12:26

标签: linux sed netcdf nco

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

netcdf myfile {
dimensions:
        time_counter = 18 ;
        depth = 50 ;
        latitude = 361 ;
        longitude = 601 ;
variables:
        salinity
        temp, etc     

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

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

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

这对我来说对于小文件很有用,但是当转储600 MB netcdf文件时,需要花费大量内存和时间。

有人知道另一种方法来实现这个目标吗?

3 个答案:

答案 0 :(得分:11)

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

我阅读了最新的NCO命令文档,并找到了一个特定于ncks" - mk_rec_dmn"的选项。 Ncks主要提取,写入或将数据附加到新的netcdf文件,然后这似乎是更好的方法,提取myfile.nc的所有数据并用新记录维度(无限维度)写入" - mk_rec_dmn& #34;没有,然后替换旧文件。

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

答案 1 :(得分:1)

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

核心问题可能是你花了很多时间将ncdump格式化文件信息到文本数据中,并且ncgen再次将文本数据解析为NetCDF文件格式。

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

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

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

可以修改那里的信息,将time_counter维度的当前长度转换为UNLIMITED的值(数字0),但如果你这样做,你真的< / em>需要验证生成的文件的完整性,正如文档巧妙地说明的那样:

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

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

任何体面的磁盘都应该在10秒左右读取/接收文件,只要你不进行交换,内存就无关紧要,因此如果采用dump + gen路由,CPU可能是你最关心的问题。 p>

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

答案 2 :(得分: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有一个很好的总结。