Opendap 和 NetCDF 不允许使用不规则索引进行提取。您只能请求开始、停止和跨步。
并且因为这是一个三角形网格,所以不能保证同一区域中三角形的节点具有相似的索引。因此,如果您只想获取边界框中的那些节点,则必须一个接一个地请求它们。这很慢。因此,在许多情况下,确定最小和最大索引并请求整个块中的一块,然后根据需要提取索引会更快。
这是python中两种方法的示例比较。在此示例中,提取包含所有索引的子集比在每个索引上循环提取时间序列快约 10 倍:
import netCDF4
import time
import numpy as np
url='http://www.smast.umassd.edu:8080/thredds/dodsC/FVCOM/NECOFS/Forecasts/NECOFS_GOM3_FORECAST.nc'
nc = netCDF4.Dataset(url)
ncv = nc.variables
lon = ncv['lon'][:]
lat = ncv['lat'][:]
tim = ncv['time'][:]
# find indices inside box
box = [-71.4,41,-70.2,41.5]
ii = (lon>=box[0])&(lon<=box[2])&(lat>=box[1])&(lat<=box[3])
# jj will have just indices from inside the box:
jj = np.where(ii)[0]
如果我们遍历每个索引,它会很慢:
# loop over indices, extracting time series
time0=time.time()
zi = np.zeros((len(tim),len(jj)))
k=0
for j in jj:
zi[:,k]=ncv['zeta'][:,j]
k +=1
print('elapsed time: %d seconds' % (time.time()-time0))
elapsed time: 56 seconds
但是如果我们在每个时间步循环遍历范围,它会快得多:
time0=time.time()
zi2 = np.zeros((len(tim),len(jj)))
jmin=jj.min()
jmax=jj.max()
for i in range(len(tim)):
ztmp = ncv['zeta'][i,jmin:jmax+1]
zi2[i,:] = ztmp[jj-jmin]
print('elapsed time: %d seconds' % (time.time()-time0))
elapsed time: 6 seconds
当然,您的结果可能会因非结构化网格的大小、子集中点的接近程度、要提取的点数等而有所不同。但希望这能让您了解所涉及的问题。