Link Search Menu Expand Document

NC檔案多維度批次篩選

Table of contents

背景

  • 提取或指定nc檔案多維度之時間、空間位置點的數值,是一件常見的工作,如。
idx=np.where(mask==0) #tuple length maybe in thousands
for i in range(len(idx[0])):
  nc[v][:,0,idx[0][i],idx[1][i]]=0  
  • 任何批次作法都遭遇困難(包括使用xarray,因此xr也是使用netcdf引擎來開啟nc檔案)
arr=nc[v][:,0,idx[0],idx[1]]  #stucked
nc[v][:,0,idx[0],idx[1]].shape  #stucked
nc[v][:,0,idx[0],idx[1]]=0  #stucked

fancy indexing applied in numpy but not in netCDF

  • 前述篩選如果是規則性的索引,適用fancy indexing
  • 而netCDF4.Dataset與numpy array指定索引的意義有很大的出入,需要注意避免錯誤:
    • numpy.array a=temp[0, 0, [0,1,2,3], [0,1,2,3]],將會得到長度4的一維序列
    • ncf a=nc['TEMP'][0, 0, [0,1,2,3], [0,1,2,3]],a.shape=(4,4)
    • 尤有進者,ncf可以接受temp[0, [0,1], [1,2,3], :],這在numpy是不可能的。
    • 二者的fancy indexing比較可以詳見netcdf-python文件
  • 所以前述stucked指令,不單是個錯誤、更會是個災難。

    arbitary indexing

  • 如果idx不是連續、或不具規則性的時空範圍
    • (idx[0],idx[1])可視為線型的軌跡陣列
    • 不適用fancy indexing
    • (目前網路上還找不到批次作業的建議方案)

nc檔案的結構與存取速度

  • 在ncf數組中執行此項任務、過程是非常緩慢的(除了indexing的意義差異)
    • netCDF4一直有個問題,就是寫出速度較netCDF3_classic為慢
    • 因為netCDF4是使用HDF5,因此是透過層級架構進行更新、壓縮、所以存取也會比較慢一些。

np.where線型篩選一個多維度nc檔案

  • 在陣列中指定部分範圍(不連續時空點)成為另外的數值,基本上是個篩選的動作。
  • nv[v][:]是個HDF5檔案,不是一般的陣列記憶體,並不適合作為篩選、置換的容器

解決方案

  • 另外開啟陣列var作為容器,令var[:,idx[0],idx[1]]=0,再一次性回存 nc[v][:]檔案中,會快很多。
...
for v in V[3]:
  var=np.zeros(shape=(nt,nrow,ncol))
  var[:,:,:]=nc[v][:,0,:,:]
  var[:,idx[0],idx[1]]=0
  nc[v][:,0,:,:]=var[:,:,:]
...

實例