16

我需要处理 netcdf 文件中的单个变量,该文件实际上包含许多属性和变量。我认为不可能更新 netcdf 文件(请参阅问题如何删除 Scientific.IO.NetCDF.NetCDFFile 中的变量?

我的方法如下:

  1. 从原始文件中获取要处理的变量
  2. 处理变量
  3. 将所有数据从原始 netcdf 但处理后的变量复制到最终文件
  4. 将处理后的变量复制到最终文件

我的问题是编写第 3 步的代码。我从以下内容开始:

def  processing(infile, variable, outfile):
        data = fileH.variables[variable][:]

        # do processing on data...

        # and now save the result
        fileH = NetCDFFile(infile, mode="r")
        outfile = NetCDFFile(outfile, mode='w')
        # build a list of variables without the processed variable
        listOfVariables = list( itertools.ifilter( lamdba x:x!=variable , fileH.variables.keys() ) )
        for ivar in listOfVariables:
             # here I need to write each variable and each attribute

如何在少量代码中保存所有数据和属性,而无需重建整个数据结构?

4

5 回答 5

18

这是我刚刚使用和工作的。@arne 的答案针对 Python 3 进行了更新,还包括复制变量属性:

import netCDF4 as nc
toexclude = ['ExcludeVar1', 'ExcludeVar2']

with netCDF4.Dataset("in.nc") as src, netCDF4.Dataset("out.nc", "w") as dst:
    # copy global attributes all at once via dictionary
    dst.setncatts(src.__dict__)
    # copy dimensions
    for name, dimension in src.dimensions.items():
        dst.createDimension(
            name, (len(dimension) if not dimension.isunlimited() else None))
    # copy all file data except for the excluded
    for name, variable in src.variables.items():
        if name not in toexclude:
            x = dst.createVariable(name, variable.datatype, variable.dimensions)
            dst[name][:] = src[name][:]
            # copy variable attributes all at once via dictionary
            dst[name].setncatts(src[name].__dict__)
于 2018-03-31T21:23:24.713 回答
8

如果您只是想复制文件并挑选出变量,nccopy这是@rewfuss 提交的一个很棒的工具。

这是一个 Pythonic(更灵活)的解决方案,带有python-netcdf4. 这允许您在写入文件之前打开它以进行处理和其他计算。

with netCDF4.Dataset(file1) as src, netCDF4.Dataset(file2) as dst:

  for name, dimension in src.dimensions.iteritems():
    dst.createDimension(name, len(dimension) if not dimension.isunlimited() else None)

  for name, variable in src.variables.iteritems():

    # take out the variable you don't want
    if name == 'some_variable': 
      continue

    x = dst.createVariable(name, variable.datatype, variable.dimensions)
    dst.variables[x][:] = src.variables[x][:]

这没有考虑变量属性,例如fill_values. 您可以按照文档轻松完成此操作。

请注意,以这种方式写入/创建的 netCDF4 文件将无法撤消。修改变量的那一刻,它会在 with 语句的末尾写入文件,或者如果您调用.close().Dataset

当然,如果您希望在编写变量之前对其进行处理,则必须注意要创建哪些维度。在新文件中,切勿在未创建变量的情况下写入变量。此外,切勿在未定义维度的情况下创建变量,如的文档中所述python-netcdf4

于 2015-08-14T04:42:34.797 回答
5

这个答案建立在 Xavier Ho ( https://stackoverflow.com/a/32002401/7666 ) 的答案之上,但是我需要修复它来完成它:

import netCDF4 as nc
import numpy as np
toexclude = ["TO_REMOVE"]
with nc.Dataset("orig.nc") as src, nc.Dataset("filtered.nc", "w") as dst:
    # copy attributes
    for name in src.ncattrs():
        dst.setncattr(name, src.getncattr(name))
    # copy dimensions
    for name, dimension in src.dimensions.iteritems():
        dst.createDimension(
            name, (len(dimension) if not dimension.isunlimited else None))
    # copy all file data except for the excluded
    for name, variable in src.variables.iteritems():
        if name not in toexclude:
            x = dst.createVariable(name, variable.datatype, variable.dimensions)
            dst.variables[name][:] = src.variables[name][:]
于 2017-03-13T09:49:22.067 回答
3

C netCDF 4.3.0 及更高版本中的 nccopy 实用程序包括一个选项,用于列出要复制的变量(连同它们的属性)。不幸的是,它不包括排除哪些变量的选项,这是您需要的。

但是,如果要包含的(以逗号分隔的)变量列表不会导致 nccopy 命令行超出系统限制,那么这将起作用。此选项有两种变体:

nccopy -v var1,var2,...,varn input.nc output.nc
nccopy -V var1,var2,...,varn input.nc output.nc

第一个 (-v) 包括所有变量定义,但仅包含命名变量的数据。第二个 (-V) 不包括未命名变量的定义或数据。

于 2013-04-16T21:50:04.667 回答
0

我知道这是一个老问题,但作为替代方案,您可以使用库netcdfshutil

import shutil
from netcdf import netcdf as nc

def processing(infile, variable, outfile):
    shutil.copyfile(infile, outfile)
    with nc.loader(infile) as in_root, nc.loader(outfile) as out_root:
        data = nc.getvar(in_root, variable)
        # do your processing with data and save them as memory "values"...
        values = data[:] * 3
        new_var = nc.getvar(out_root, variable, source=data)
        new_var[:] = values
于 2015-08-15T22:26:31.903 回答