从NetCDF文件中提取变量数据值的min/max
的常用方法是,与scipy.io.netcdf
相比,切换到netCDF4 Python模块时的速度要慢一些。
我正在使用相对较大的海洋模型输出文件(来自ROMS),在给定的地图区域(夏威夷)上具有多个深度级别。当这些在NetCDF-3中时,我使用了scipy.io.netcdf
。
现在这些文件都在NetCDF-4(“经典”)中,我不能再使用scipy.io.netcdf
而是转而使用netCDF4 Python模块。然而,缓慢是一个问题,我想知道是否有一种更有效的方法来提取变量的数据范围(最小和最大数据值)?
这是我使用scipy的NetCDF-3方法:
import scipy.io.netcdf
netcdf = scipy.io.netcdf.netcdf_file(file)
var = netcdf.variables['sea_water_potential_temperature']
min = var.data.min()
max = var.data.max()
这是我使用netCDF4的NetCDF-4方法:
import netCDF4
netcdf = netCDF4.Dataset(file)
var = netcdf.variables['sea_water_potential_temperature']
var_array = var.data.flatten()
min = var_array.data.min()
max = var_array.data.max()
值得注意的是,我必须首先在netCDF4中展平数据数据,这个操作显然会减慢速度。
有更好/更快的方式吗?
答案 0 :(得分:1)
根据hpaulj
的建议,这是一个使用nco
调用ncwa
命令subprocess
的函数。它在使用OPeNDAP地址时非常糟糕,我手边没有任何文件可以在本地测试。
您可以看到它是否适合您以及速度差异。
这假设您安装了nco
库。
def ncwa(path, fnames, var, op_type, times=None, lons=None, lats=None):
'''Perform arithmetic operations on netCDF file or OPeNDAP data
Args
----
path: str
prefix
fnames: str or iterable
Names of file(s) to perform operation on
op_type: str
ncwa arithmetic operation to perform. Available operations are:
avg,mabs,mebs,mibs,min,max,ttl,sqravg,avgsqr,sqrt,rms,rmssdn
times: tuple
Minimum and maximum timestamps within which to perform the operation
lons: tuple
Minimum and maximum longitudes within which to perform the operation
lats: tuple
Minimum and maximum latitudes within which to perform the operation
Returns
-------
result: float
Result of the operation on the selected data
Note
----
Adapted from the OPeNDAP examples in the NCO documentation:
http://nco.sourceforge.net/nco.html#OPeNDAP
'''
import os
import netCDF4
import numpy
import subprocess
output = 'tmp_output.nc'
# Concatenate subprocess command
cmd = ['ncwa']
cmd.extend(['-y', '{}'.format(op_type)])
if times:
cmd.extend(['-d', 'time,{},{}'.format(times[0], times[1])])
if lons:
cmd.extend(['-d', 'lon,{},{}'.format(lons[0], lons[1])])
if lats:
cmd.extend(['-d', 'lat,{},{}'.format(lats[0], lats[1])])
cmd.extend(['-p', path])
cmd.extend(numpy.atleast_1d(fnames).tolist())
cmd.append(output)
# Run cmd and check for errors
subprocess.run(cmd, stdout=subprocess.PIPE, check=True)
# Load, read, close data and delete temp .nc file
data = netCDF4.Dataset(output)
result = float(data[var][:])
data.close()
os.remove(output)
return result
path = 'https://ecowatch.ncddc.noaa.gov/thredds/dodsC/hycom/hycom_reg6_agg/'
fname = 'HYCOM_Region_6_Aggregation_best.ncd'
times = (0.0, 48.0)
lons = (201.5, 205.5)
lats = (18.5, 22.5)
smax = ncwa(path, fname, 'salinity', 'max', times, lons, lats)
答案 1 :(得分:1)
如果只是通过变量数组获取最小/最大值,则可以使用xarray。
%matplotlib inline
import xarray as xr
da = xr.open_dataset('infile/file.nc')
max = da.sea_water_potential_temperature.max()
min = da.sea_water_potential_temperature.min()
这应该分别为您提供一个最小值/最大值。您还可以获得跨选定维度(例如时间,经度,纬度等)的变量的最小值/最大值。Xarray非常适合处理多维数组,这就是为什么当您不使用其他操作工具时在Python中处理NetCDF非常容易的原因像CDO和NCO。 最后,xarray还用于其他相关库中,这些库以python(http://xarray.pydata.org/en/stable/related-projects.html)处理天气和气候数据。
答案 2 :(得分:1)
我的软件包nctoolkit(https://pypi.org/project/nctoolkit/ https://nctoolkit.readthedocs.io/en/latest/installing.html)是一个Python解决方案(使用CDO作为后端)。
它具有许多内置的方法来计算不同类型的最小/最大值。
我们首先需要将文件作为数据集读取:
将nctoolkit导入为nc
data = nc.open_data(file)
如果要在每个时间步长上跨空间使用最大值,请执行以下操作:
data.spatial_max()
每个网格单元和时间步长在所有深度上的最大值将计算如下:
data.vertical_max()
如果您想要跨时间的最大值,可以这样做:
data.max()
这些方法是可链接的,并且CDO后端非常高效,因此对于处理ROMS数据应该是理想的选择。