file-io - 编写 netcdf4 文件比编写 netcdf3_classic 文件慢 6 倍,而文件大 8 倍?

标签 file-io netcdf

我在 python 中使用 netCDF4 库,刚遇到标题中所述的问题。起初我将此归咎于团体,但事实证明这是 NETCDF4 和 NETCDF3_CLASSIC 格式之间的差异(编辑:它似乎与我们的 Linux 安装 netcdf 库有关)。

在下面的程序中,我以两种不同的方式创建了一个包含相同数据的简单时间序列 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 方法中的格式参数。这是错误还是功能?

谢谢,马丁

编辑:我现在发现这一定与我们在 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')

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

最佳答案

这两种文件格式确实有不同的特点。经典文件格式非常简单(嗯,比新格式更简单:http://www.unidata.ucar.edu/software/netcdf/docs/netcdf/Classic-Format-Spec.html#Classic-Format-Spec):一个小标题描述所有数据,然后(因为你有 3 个记录变量)3 个记录变量交错。

很好也很简单,但是你只有一个无限的维度,没有并行 I/O 的工具,也没有办法将数据分组管理。

进入 NetCDF-4 中引入的基于 HDF5 的新后端。

为了换取新功能、更大的灵 active 以及对文件和变量大小的更少限制,您必须付出一些代价。对于大型数据集,成本是摊销的,但您的变量(相对而言)有点小。

我认为您使用记录变量会加剧文件大小差异。为了支持 N 维数组的增长,Netcdf-4 格式的每个记录条目都有更多的元数据。

HDF5 也使用“读者做对”的约定。经典的 NetCDF 说“所有数据都将是大端”,但是 HDF5 编码了一些关于数据存储方式的信息。如果读取进程与写入进程的架构相同(这很常见,就像在您的笔记本电脑上或从模拟检查点重新启动一样),则无需进行转换。

关于file-io - 编写 netcdf4 文件比编写 netcdf3_classic 文件慢 6 倍,而文件大 8 倍?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27164414/

相关文章:

python - 如何使用 python netCDF4 创建 netCDF 文件?

python - python netCDF4 中的纬度和经度表示

python - 如果我不将文件分配给变量,文件会自动关闭吗?

java - 将文本文件中的行堆栈连接到一行中

c - Strtol 未返回正确的 endptr - C

r 读取 NetCDF 并导出为 shapefile

duplicates - 将 NetCDF 文件中的每月数据复制为双月数据

fortran - 在 netcdf 文件中写入变量

java - 写入文件时插入换行符?

java - 在文件输入输出java中使用数组列表