解释子集数据xarray的索引编制速度差异

时间:2018-10-22 12:58:33

标签: python python-xarray

对于气象应用程序,我想从网络上下载天气模型数据(1x1度网格)。在这里,我想从60W到40E和30N到70N的数据中选择一个时间步长和一个级别。为此,我使用xarray加载数据。因此,数据集本身的大小为[40-lat x 100-lon]。因此,我想从大数据集中获得一小部分选择。

在尝试获取数据时,我遇到了与索引有关的(对我而言)无法解释的事情。如果我想使用sel()方法来选择数据,而方法是在本初子午线上进行取值(这里称为“立即选择”方法),那么选择的速度就很慢(在我的计算机上大约需要20秒)。但是,如果我采用另一种方法-在Prime Meridian之前下载数据,然后下载通过Prime Meridian的数据,最后使用np.concatenate(现在称为“ concatenation-method”)合并数据集-速度快了两个订单,平均花费我的计算机0.5秒。

关于这种下载数据行为的问题如下:

  1. 是什么解释了为什么第二种“串联”方法比第一种“立即选择”方法快得多的原因?
  2. 是否可以将“立即选择”方法重新设计为与“串联”方法一样快?

下面是用于下载数据的代码的第一部分:

from netCDF4 import Dataset
import numpy as np
import xarray as xr
import time as tm

# User settings
year_range_run = np.array([2018])
month_range_run = np.array([10])
day_range_run = np.array([22])
hour_range_run = np.array([0]) 

year_range_output = np.array([2018])
month_range_output = np.array([10])
day_range_output = np.array([22])
hour_range_output = np.array([12]) 

# Select data at one level from 30 to 70 N and from 60W to 40E
lat_range = np.arange(30, 71, 1)
lon_range = np.arange(-60, 41, 1)
lon_range = np.where(lon_range<0, lon_range+360, lon_range)
lev_range = np.array([1000])

# Convert user lon selection ranging from 0 to 360 rather than -180 to 180
lon_toselect = np.where(lon_range<0, lon_range+360, lon_range)
lat_toselect = lat_range
lev_toselect = lev_range

# Define date string to define  file to download. 
yearstr = str(year_range_run[0])
monthstr = str(month_range_run[0]) if month_range_run[0] >= 10 else '0' + str(month_range_run[0])
daystr = str(day_range_run[0]) if day_range_run[0] >= 10 else '0' + str(day_range_run[0])

totalstr = yearstr + monthstr + daystr

# Define location of server data
serverstring = 'http://nomads.ncep.noaa.gov:9090/dods/gfs_1p00/gfs'\
+ totalstr\
+ '/gfs_1p00_00z'

# Load data
dataset = xr.open_dataset(serverstring)
time = dataset.variables['time']
lat = dataset.variables['lat']
lon = dataset.variables['lon']
lev = dataset.variables['lev']

最后,这是速度测试:

# Load data into memory via subsetting data before and after Prime Meridian, and 
# concatenating data afterwards ('concatenation' method)
t1 = tm.time()
d1 = dataset.sel(time=time[0], lev=lev[0], lat=lat_range, lon=lon_range[:60])
var1 = d1.hgtprs.values
d2 = dataset.sel(time=time[0], lev=lev[0], lat=lat_range, lon=lon_range[60:])
var2 = d2.hgtprs.values
var3 = np.concatenate((var1, var2), axis=-1)
t2 = tm.time()

# Load data into memory via subsetting data before and after Prime Meridian at
# once ('immediate selection' method)
d3 = dataset.sel(time=time[0],lev=lev[0], lat = lat_range, lon = lon_range)
var4= d3.hgtprs.values
t3 = tm.time()

dt1 = t2-t1  # The time it takes to select the data using the concatenation method 
# fast
dt2 = t3-t2  # The time it takes to select data using the 'immediate selection' method
# much slower than the 'concatenation' method
print(dt1, dt2)

0 个答案:

没有答案