如何在python中读取gzip netcdf文件?

时间:2014-12-05 18:18:45

标签: python gzip netcdf

我有一个有效的python程序,它使用netCDF4模块中的Dataset命令读入大量的netCDF文件。以下是相关部分的片段:

from netCDF4 import Dataset
import glob

infile_root = 'start_of_file_name_'

for infile in sorted(glob.iglob(infile_root + '*')):
   ncin = Dataset(infile,'r')
   ncin.close()

我想修改它以读取gzip压缩的netCDF文件。文件本身在创建后进行了压缩;它们没有内部压缩(即文件是* .nc.gz)。如果我正在阅读gzip压缩文本文件,那么命令将是:

from netCDF4 import Dataset
import glob
import gzip

infile_root = 'start_of_file_name_'

for infile in sorted(glob.iglob(infile_root + '*.gz')):
   f = gzip.open(infile, 'rb')
   file_content = f.read()
   f.close()

在谷歌上搜索半小时后阅读netCDF4文档后,我能为netCDF文件做到这一点的唯一方法是:

from netCDF4 import Dataset
import glob
import os

infile_root = 'start_of_file_name_'

for infile in sorted(glob.iglob(infile_root + '*.gz')):
   os.system('gzip -d ' + infile)
   ncin = Dataset(infile[:-3],'r')
   ncin.close()
   os.system('gzip ' + infile[:-3]) 

是否可以直接使用Dataset命令读取gzip文件?或者没有通过os调用gzip?

3 个答案:

答案 0 :(得分:5)

因为NetCDF4-Python包装了C NetCDF4库,所以只要使用gzip模块传入类文件对象就不行了。正如@tdelaney所建议的那样,唯一的选择是使用gzip提取到临时文件。

如果您碰巧对这些文件的创建有任何控制权,NetCDF版本4文件在内部支持zlib压缩,因此使用gzip是多余的。如果您需要重复处理这些文件,也可能值得将文件从版本3转换为版本4.

答案 1 :(得分:4)

从netCDF4-1.2.8(Changelog)开始,支持从内存读取数据集:

import netCDF4
import gzip

with gzip.open('test.nc.gz') as gz:
    with netCDF4.Dataset('dummy', mode='r', memory=gz.read()) as nc:
        print(nc.variables)

请参阅Dataset documentation中的memory参数的说明

答案 2 :(得分:2)

由于我必须解决同样的问题,这是一个现成的解决方案:

import gzip
import os
import shutil
import tempfile

import netCDF4

def open_netcdf(fname):
    if fname.endswith(".gz"):
        infile = gzip.open(fname, 'rb')
        tmp = tempfile.NamedTemporaryFile(delete=False)
        shutil.copyfileobj(infile, tmp)
        infile.close()
        tmp.close()
        data = netCDF4.Dataset(tmp.name)
        os.unlink(tmp.name)
    else:
        data = netCDF4.Dataset(fname)
    return data