编写netcdf4文件比编写netcdf3_classic文件慢6倍,文件大8倍?

时间:2014-11-27 06:32:19

标签: file-io netcdf

我在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')

[旧代码被删除,因为它有太多不必要的东西]

2 个答案:

答案 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模块之间的相互作用相关的特定于站点的问题。