我在python中使用netCDF4库,刚刚遇到标题中所述的问题。起初我是指责组,但事实证明它是NETCDF4和NETCDF3_CLASSIC格式之间的区别(编辑:它似乎与我们的netcdf库的Linux安装有关)。
在下面的程序中,我以两种不同的方式创建一个简单的相同数据的时间序列netcdf文件:1)作为NETCDF3_CLASSIC文件,2)作为NETCDF4平面文件(在netcdf4文件中创建组不会太多差异)。我通过简单的时序和ls命令找到的是:
1) NETCDF3 1.3483 seconds 1922704 bytes
2) NETCDF4 flat 8.5920 seconds 15178689 bytes
创建1)和2)的例程完全相同,唯一的区别是netCDF4.Dataset方法中的format参数。这是一个错误还是一个功能?
谢谢,马丁
编辑:我现在发现这必须与我们在Linux计算机上本地安装netcdf库有关。当我在Windows笔记本电脑上使用下面的程序版本(精简到必需品)时,我得到了类似的文件大小,而netcdf4实际上几乎是netcdf3的2倍!当我在我们的linux系统上运行相同的程序时,我可以重现旧的结果。因此,这个问题显然与python无关。
很抱歉这个混乱。
新代码:
import datetime as dt
import numpy as np
import netCDF4 as nc
def write_to_netcdf_single(filename, data, series_info, format='NETCDF4'):
vname = 'testvar'
t0 = dt.datetime.now()
with nc.Dataset(filename, "w", format=format) as f:
# define dimensions and variables
dim = f.createDimension('time', None)
time = f.createVariable('time', 'f8', ('time',))
time.units = "days since 1900-01-01 00:00:00"
time.calendar = "gregorian"
param = f.createVariable(vname, 'f4', ('time',))
param.units = "kg"
# define global attributes
for k, v in sorted(series_info.items()):
setattr(f, k, v)
# store data values
time[:] = nc.date2num(data.time, units=time.units, calendar=time.calendar)
param[:] = data.value
t1 = dt.datetime.now()
print "Writing file %s took %10.4f seconds." % (filename, (t1-t0).total_seconds())
if __name__ == "__main__":
# create an array with 1 mio values and datetime instances
time = np.array([dt.datetime(2000,1,1)+dt.timedelta(hours=v) for v in range(1000000)])
values = np.arange(0., 1000000.)
data = np.array(zip(time, values), dtype=[('time', dt.datetime), ('value', 'f4')])
data = data.view(np.recarray)
series_info = {'attr1':'dummy', 'attr2':'dummy2'}
filename = "testnc4.nc"
write_to_netcdf_single(filename, data, series_info)
filename = "testnc3.nc"
write_to_netcdf_single(filename, data, series_info, format='NETCDF3_CLASSIC')
[旧代码被删除,因为它有太多不必要的东西]
答案 0 :(得分:0)
这两种文件格式具有不同的特征。经典的文件格式很简单(好吧,比新格式更简单:http://www.unidata.ucar.edu/software/netcdf/docs/netcdf/Classic-Format-Spec.html#Classic-Format-Spec):一个小标题描述了所有数据,然后(因为你有3个记录变量),3个记录变量得到交错。 / p>
既简单又简单,但您只获得一个无限维度,没有并行I / O的功能,也无法将数据管理到组中。
进入NetCDF-4中引入的新的基于HDF5的后端。
为了换取新功能,更大的灵活性以及更少的文件和可变大小限制,您需要付出一点代价。对于大型数据集,成本是摊销的,但您的变量(相对而言)很小。
我认为使用记录变量会加剧文件大小差异。为了支持N维中可扩展的阵列,Netcdf-4格式中的每个记录条目都有更多的元数据。
HDF5使用"阅读器正确"惯例也是。经典NetCDF表示"所有数据都是big-endian",但HDF5会编码一些有关数据存储方式的信息。如果读者进程与编写器进程的结构相同(这是常见的,就像在笔记本电脑上或从模拟检查点重新启动一样),则不需要进行转换。
答案 1 :(得分:-1)
这个问题不太可能帮助其他人,因为它似乎是与netcdf库和python netCDF4模块之间的相互作用相关的特定于站点的问题。