Как читать файл gcip netcdf в python?

У меня есть работающая программа python, которая читает в большом количестве больших файлов netCDF, используя команду Dataset из модуля netCDF4. Вот фрагмент соответствующих частей:

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() 

Я хочу изменить это, чтобы читать в файлах netCDF, которые gzipped. После создания самих файлов были созданы gzip; они не внутренне сжаты (т.е. файлы * .nc.gz). Если бы я читал текстовые файлы gzipped, команда была бы:

 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]) 

Возможно ли напрямую читать файлы gzip с помощью команды Dataset? Или иначе не называть gzip через os?

Поскольку 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