簡體   English   中英

按維度名稱提取netcdf4變量切片

[英]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,:,:]

鑒於我知道尺寸的名稱,例如ABCD 如何通過尺寸名稱而不是位置進行訪問?

您可以使用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].shapenc_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM