lat lon 子集的 netcdf4 提取
netcdf4 extract for subset of lat lon
我想提取一个相当大的 netcdf 文件的空间子集。来自 Loop through netcdf files and run calculations - Python or R
from pylab import *
import netCDF4
f = netCDF4.MFDataset('/usgs/data2/rsignell/models/ncep/narr/air.2m.1989.nc')
# print variables
f.variables.keys()
atemp = f.variables['air'] # TODO: extract spatial subset
如何只提取对应于某个州(例如爱荷华州)的 netcdf 文件的子集。爱荷华州的边界经纬度如下:
经度:西经 89° 5' 至西经 96° 31'
纬度:北纬 40° 36' 至北纬 43° 30'
好吧,这很简单,你必须找到纬度和经度上下限的索引。
您可以通过查找最接近您要查找的值的值来实现。
latbounds = [ 40 , 43 ]
lonbounds = [ -96 , -89 ] # degrees east ?
lats = f.variables['latitude'][:]
lons = f.variables['longitude'][:]
# latitude lower and upper index
latli = np.argmin( np.abs( lats - latbounds[0] ) )
latui = np.argmin( np.abs( lats - latbounds[1] ) )
# longitude lower and upper index
lonli = np.argmin( np.abs( lons - lonbounds[0] ) )
lonui = np.argmin( np.abs( lons - lonbounds[1] ) )
然后只需对变量数组进行子集化。
# Air (time, latitude, longitude)
airSubset = f.variables['air'][ : , latli:latui , lonli:lonui ]
- 注意,我假设经度维度变量以东度为单位,空气变量具有时间、纬度、经度维度。
Favo 的回答有效(我假设;尚未检查)。一种更直接和惯用的方法是使用 numpy 的 where 函数来查找必要的索引。
lats = f.variables['latitude'][:]
lons = f.variables['longitude'][:]
lat_bnds, lon_bnds = [40, 43], [-96, -89]
lat_inds = np.where((lats > lat_bnds[0]) & (lats < lat_bnds[1]))
lon_inds = np.where((lons > lon_bnds[0]) & (lons < lon_bnds[1]))
air_subset = f.variables['air'][:,lat_inds,lon_inds]
请注意,使用 NCO's ncks.
在命令行上可以更快地完成此操作
ncks -v air -d latitude,40.,43. -d longitude,-89.,-96. infile.nc -O subset_infile.nc
如果你喜欢 pandas,那么你应该考虑查看 xarray。
import xarray as xr
ds = xr.open_dataset('http://geoport.whoi.edu/thredds/dodsC/usgs/data2/rsignell/models/ncep/narr/air.2m.1980.nc',
decode_cf=False)
lat_bnds, lon_bnds = [40, 43], [-96, -89]
ds.sel(lat=slice(*lat_bnds), lon=slice(*lon_bnds))
要反映 N1B4 的响应,您也可以与气候数据操作员 (cdo) 联机完成:
cdo sellonlatbox,-96.5,-89,40,43 in.nc out.nc
为了遍历一组文件,我会在 BASH 脚本中执行此操作,使用 cdo 处理每个文件,然后调用您的 python 脚本:
#!/bin/bash
# pick up a list of files (I'm presuming the loop is over the years)
files=`ls /usgs/data2/rsignell/models/ncep/narr/air.2m.*.nc`
for file in $files ; do
# extract the location, I haven't used your exact lat/lons
cdo sellonlatbox,-96.5,-89,40,43 $file iowa.nc
# Call your python or R script here to process file iowa.nc
python script
done
我总是尝试进行文件处理 "offline",因为我发现它不太容易出错。 cdo 是 ncks 的替代品,我并不是说它更好,我只是觉得它更容易记住命令。 nco 通常更强大,当 cdo 无法执行我希望执行的任务时,我会求助于它。
lonbounds部分需要稍微改动一下(数据为东度),因为数据中的经度取值范围是0到359,所以负数在这种情况下不起作用。另外,latli 和 latui 的计算需要转换,因为值从北到南,89 到 -89。
latbounds = [ 40 , 43 ]
lonbounds = [ 260 , 270 ] # degrees east
lats = f.variables['latitude'][:]
lons = f.variables['longitude'][:]
# latitude lower and upper index
latli = np.argmin( np.abs( lats - latbounds[1] ) )
latui = np.argmin( np.abs( lats - latbounds[0] ) )
# longitude lower and upper index
lonli = np.argmin( np.abs( lons - lonbounds[0] ) )
lonui = np.argmin( np.abs( lons - lonbounds[1] ) )
如果您在 Linux 或 macOS 中工作,这可以使用 nctoolkit (https://nctoolkit.readthedocs.io/en/latest/) 轻松处理:
import nctoolkit as nc
data = nc.open_data('/usgs/data2/rsignell/models/ncep/narr/air.2m.1989.nc')
data.crop(lon = [-(96+31/60), -(89+5/6)], lat = [40 + 36/60, 43 + 30/60])
我想提取一个相当大的 netcdf 文件的空间子集。来自 Loop through netcdf files and run calculations - Python or R
from pylab import *
import netCDF4
f = netCDF4.MFDataset('/usgs/data2/rsignell/models/ncep/narr/air.2m.1989.nc')
# print variables
f.variables.keys()
atemp = f.variables['air'] # TODO: extract spatial subset
如何只提取对应于某个州(例如爱荷华州)的 netcdf 文件的子集。爱荷华州的边界经纬度如下:
经度:西经 89° 5' 至西经 96° 31'
纬度:北纬 40° 36' 至北纬 43° 30'
好吧,这很简单,你必须找到纬度和经度上下限的索引。 您可以通过查找最接近您要查找的值的值来实现。
latbounds = [ 40 , 43 ]
lonbounds = [ -96 , -89 ] # degrees east ?
lats = f.variables['latitude'][:]
lons = f.variables['longitude'][:]
# latitude lower and upper index
latli = np.argmin( np.abs( lats - latbounds[0] ) )
latui = np.argmin( np.abs( lats - latbounds[1] ) )
# longitude lower and upper index
lonli = np.argmin( np.abs( lons - lonbounds[0] ) )
lonui = np.argmin( np.abs( lons - lonbounds[1] ) )
然后只需对变量数组进行子集化。
# Air (time, latitude, longitude)
airSubset = f.variables['air'][ : , latli:latui , lonli:lonui ]
- 注意,我假设经度维度变量以东度为单位,空气变量具有时间、纬度、经度维度。
Favo 的回答有效(我假设;尚未检查)。一种更直接和惯用的方法是使用 numpy 的 where 函数来查找必要的索引。
lats = f.variables['latitude'][:]
lons = f.variables['longitude'][:]
lat_bnds, lon_bnds = [40, 43], [-96, -89]
lat_inds = np.where((lats > lat_bnds[0]) & (lats < lat_bnds[1]))
lon_inds = np.where((lons > lon_bnds[0]) & (lons < lon_bnds[1]))
air_subset = f.variables['air'][:,lat_inds,lon_inds]
请注意,使用 NCO's ncks.
在命令行上可以更快地完成此操作ncks -v air -d latitude,40.,43. -d longitude,-89.,-96. infile.nc -O subset_infile.nc
如果你喜欢 pandas,那么你应该考虑查看 xarray。
import xarray as xr
ds = xr.open_dataset('http://geoport.whoi.edu/thredds/dodsC/usgs/data2/rsignell/models/ncep/narr/air.2m.1980.nc',
decode_cf=False)
lat_bnds, lon_bnds = [40, 43], [-96, -89]
ds.sel(lat=slice(*lat_bnds), lon=slice(*lon_bnds))
要反映 N1B4 的响应,您也可以与气候数据操作员 (cdo) 联机完成:
cdo sellonlatbox,-96.5,-89,40,43 in.nc out.nc
为了遍历一组文件,我会在 BASH 脚本中执行此操作,使用 cdo 处理每个文件,然后调用您的 python 脚本:
#!/bin/bash
# pick up a list of files (I'm presuming the loop is over the years)
files=`ls /usgs/data2/rsignell/models/ncep/narr/air.2m.*.nc`
for file in $files ; do
# extract the location, I haven't used your exact lat/lons
cdo sellonlatbox,-96.5,-89,40,43 $file iowa.nc
# Call your python or R script here to process file iowa.nc
python script
done
我总是尝试进行文件处理 "offline",因为我发现它不太容易出错。 cdo 是 ncks 的替代品,我并不是说它更好,我只是觉得它更容易记住命令。 nco 通常更强大,当 cdo 无法执行我希望执行的任务时,我会求助于它。
lonbounds部分需要稍微改动一下(数据为东度),因为数据中的经度取值范围是0到359,所以负数在这种情况下不起作用。另外,latli 和 latui 的计算需要转换,因为值从北到南,89 到 -89。
latbounds = [ 40 , 43 ]
lonbounds = [ 260 , 270 ] # degrees east
lats = f.variables['latitude'][:]
lons = f.variables['longitude'][:]
# latitude lower and upper index
latli = np.argmin( np.abs( lats - latbounds[1] ) )
latui = np.argmin( np.abs( lats - latbounds[0] ) )
# longitude lower and upper index
lonli = np.argmin( np.abs( lons - lonbounds[0] ) )
lonui = np.argmin( np.abs( lons - lonbounds[1] ) )
如果您在 Linux 或 macOS 中工作,这可以使用 nctoolkit (https://nctoolkit.readthedocs.io/en/latest/) 轻松处理:
import nctoolkit as nc
data = nc.open_data('/usgs/data2/rsignell/models/ncep/narr/air.2m.1989.nc')
data.crop(lon = [-(96+31/60), -(89+5/6)], lat = [40 + 36/60, 43 + 30/60])