我每天下载具有以下结构的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文件时,需要花费大量内存和时间。
有人知道另一种方法来实现这个目标吗?
答案 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})
结合Dask
和xarray
linked here有一个很好的总结。