我有一个大的(5GB)温度netCDF文件。该文件有4个维度:时间,压力等级,纬度,经度。
数据集有31个时间点,我只对5个压力水平感兴趣。
我的参数是温度t
:
from netCDF4._netCDF4 import Dataset
# Load the dataset
dataset = Dataset(path)
factor = dataset.variables['t']
要从中心单元格周围的factor
变量中提取温度数据的“立方体”,我会简单地进行子集化,如下所示:
radius = 5
# +1 because the subsetting does not include last index
lats_bounds = [nearest_latitude_index-radius,nearest_latitude_index+radius + 1]
lons_bounds = [nearest_longitude_index-radius,nearest_longitude_index+radius +1]
#all timepoints
times_bounds = [0, len(times)]
#just the last 5 pressure levels
pressure_level_bounds = [len(levels)-5, len(levels)]
results = factor[times_bounds[0]:times_bounds[1],pressure_level_bounds[0]:pressure_level_bounds[1], lats_bounds[0]:lats_bounds[1],lons_bounds[0]:lons_bounds[1]]
问题是results
现在的ndarray
类型的形状为(31,5,11,11)
,大小为18755
(31 * 5 * 11 * 11),其中每个索引只包含一个单一价值。
我需要来自results
的值,但对于每个值,我还需要相应的时间点,压力等级,纬度和经度。
理想情况下,我想像我一样做子集,但我的最终结果将是一系列元组......像这样:
# corresponding timestamp, pressure level, latitude, longitude
# and the temperature value extracted.
final = [
(2342342, 1000, 24.532, 53.531, 277),
(2342342, 1000, 74.453, 26.123, 351),
(2342342, 1000, 80.311, 56,345, 131),
...
]
我怎样才能做到这一点?
答案 0 :(得分:1)
查看xarray的isel。从netCDF4翻译语法看起来像这样:
ds = xr.open_dataset(path)
factor = ds['t']
# note that levels/lon/lat are the names of dimensions in your Dataset
subset = factor.isel(levels=slice(-5, None),
lon=[1, 18, 48, 99], lat=[16, 28, 33, 35])
stacked = subset.stack(points=('time', 'levels', 'lon', 'lat'))
# This subset can be converted to a `pandas.Series`:
data = stacked.to_pandas()
# or it can be converted to a list of tuples
df = data.reset_index()
final = [tuple(row[1].values) for row in df.iterrows()]
Xarray还支持基于标签的索引器(即lat=[29.3, 42.3]
),但为此,您应该使用sel
方法而不是isel
。
答案 1 :(得分:-2)
我将Pandas用于此任务。但由于你只有35次和5次压力,我首先简化你的方法并找出如何做一个单一的时间和压力水平和一个lat,lon。然后弄清楚如何循环通过这些索引来获得你的元组。类似的东西:
for i in range(0, len(times)):
for j in range(0, len(levels):
print( results[i, j, nearest_lat_idx, nearest_lon_idx) )
当然你也可以为lat和lon添加循环,但它有点难看。