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

如何在python中读取gzip netcdf文件?,python,gzip,netcdf,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() 我想修改它以

我有一个工作的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文件。文件本身在创建后被gzip压缩;它们不是内部压缩的(即文件为*.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文档后,我能想到的唯一方法是:

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文件?或者不通过操作系统调用gzip?

因为NetCDF4 Python封装了C NetCDF4库,所以使用gzip模块传入一个类似文件的对象是不走运的。唯一的选择是,正如@tdelaney所建议的,使用gzip提取到一个临时文件


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

因为我刚刚解决了同样的问题,这里有一个现成的解决方案:

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

自netCDF4-1.2.8()以来,支持从内存读取数据集:


请参阅

中的
memory
参数的描述,不要指定任何关于gz文件的内容,因此我认为它不受支持。我确信有一种方法可以从Python中压缩它们,而无需
gzip
系统调用,但我不知道会是什么。为什么需要数据集来处理它?我不想分别调用解压然后重新gzip文件。我还主要希望避免系统调用。
gzip.open
返回一个类似文件的对象,可用于对文件的只读访问,但netCDF4似乎不支持该操作。如果是我,我会使用Pythongzip模块解压缩到一个临时文件,而不使用原始文件。如果这是需要经常做的事情,您可以开始维护已解压缩内容的缓存。如果文件被修改,您“”无论如何都需要解压和重新压缩,所以管它呢。@tdelaney-谢谢。使用gzip模块解压缩到临时文件是一个很好的建议。
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)