[英]Extract netcdf4 variable slice by dimension name
我有一個4維的netCDF文件。 我想通過給出尺寸之一的名稱從netCDF文件中提取一個切片
我知道如何按位置執行此操作。 例如
from netCDF4 import Dataset
hndl_nc = Dataset(path_to_nc)
# Access by slice
hndl_nc.variables['name_variable'][:,5,:,:]
鑒於我知道尺寸的名稱,例如A
, B
, C
, D
。 如何通過尺寸名稱而不是位置進行訪問?
您可以使用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))
看來目前最接近的解決方案是
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
方法之間的主要差異。
希望有人能對此提供更完整的答案; 對於不同的數據集將非常有用。
因此,我可能想出了一些可以稱為“ 解決方案 ”的東西。
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
和nc_fid[var].shape
非常容易),則可以根據列表的位置簡單地排列列表。每個維度。 例如,如果您擁有形狀時間為lon等於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]
將花費1 毫秒 。 非常神秘; 無論如何,顯然您應該嘗試確保list_query
不只是整數列表。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.