我有一个4维的netCDF文件。我想通过给出其中一个维度
的名称从netCDF文件中提取切片我知道如何通过职位来做到这一点。 E.g。
from netCDF4 import Dataset
hndl_nc = Dataset(path_to_nc)
# Access by slice
hndl_nc.variables['name_variable'][:,5,:,:]
鉴于我知道维度的名称,请说A
,B
,C
,D
。如何按尺寸名称而不是位置进行访问?
答案 0 :(得分:1)
您可以使用xarray的索引功能按维度名称访问netcdf数据。
import xarray as xr
ds = xr.open_dataset('./foo.nc')
var = ds['name_variable']
# Slice var by Dimension "A" between values 0 and 5
var_slice = var.sel(A=slice(0,5))
答案 1 :(得分:1)
目前最接近的解决方案似乎是
np.take(nc4_variable[:],dim_ids,axis=dim)
或
nc4_variable[:].take(dim_ids,axis=dim)
其中dim_ids
是切片的列表或元组,dim
是您要切片的维度。不幸的是,这似乎首先加载了整个数据集,并且似乎并没有解决这个问题; [:]
是必要的。在第一种方法中忽略它会在不调整add_offset
,_FillValue
等参数的情况下加载数据;在第二种方法中忽略它会产生错误。
在Ipython中使用%timeit
进行测试,确认了正常切片与np.take
方法之间的主要区别。
希望有人能够提出更完整的答案;对各种数据集非常有用。
答案 2 :(得分:0)
所以,我可能想出一些可以作为" 解决方案"
的资格。numpy数组显然可以使用单例迭代列表进行索引,例如
a = np.reshape(range(0,16),(4,4),order='F')
a = a[ [[0,1], [1]] ]
返回a
等于array([4,5])
。另一个例子是[[range(3),[1 2],3]]
。这些单例列表以*subscripts
的方式展开,就像您直接查询a[[0,1],1]
而不是a[ [[0,1],1] ]
一样。
因此,如果您能够查询netCDF变量中每个维度的位置和长度(使用nc_fid[var].dimension
和nc_fid[var].shape
非常简单),那么您只需根据位置置换列表即可每个维度。例如,如果您有按lon by lat的形状时间数据,并且您想要所有经度,所有纬度和时间索引t=5
,则可以使用
order_want = ['lon', 'lat', 'time'] # must figure out dimension names a priori
nlon = nc_fid[var].shape[nc_fid[var].dimensions.index('lon')]
nlat = nc_fid[var].shape[nc_fid[var].dimensions.index('lat')]
ids = [ range(0,nlon), range(0,nlat), 5 ]
ids_permute = [order_want.index(n) for n in nc_fid[var].dimensions]
ids_query = [l[i] for l,i in zip(ids,ids_permute)]
sliced_data = nc_fid[var][list_query]
这不需要维度位置的先验知识,不需要加载变量的所有维度。
请注意,在IPython中进行了一些%timeit
测试后,似乎所有整数索引都有一些特殊的延迟,例如: list_query = [0,0,0,0]
将 80ms ,而list_query = [range(1),0,0,0]
甚至list_query = [[0,1,2,3,4,5],0,0,0]
将 1ms 。非常神秘;无论如何,显然你应该尝试确保list_query
不仅仅是一个整数列表。