區域範圍讀取NC文件,經緯向切片取值問題

問題:

按照區域範圍(min_lat, max_lat)~(min_lon, max_lon)讀取一個NC文件,經、緯數據切片如何獲取維數是一個大問題,切片數量不當,容易導致微小的誤差,在後續的矩陣運算帶來大的災難。

例如:依據小間距網格計算結果,需與大間距網格數據進行誤差比較時,一般會對小間距風格數據進行插值,此時因爲插值後的網格精度是確定的,所以需要根據區域範圍,計算出插值後的經緯向維數值1,利用維數值進行遍歷插值。

而根據區域範圍直接讀取大間距網格數據,需要確定切片取值的經緯向維數值2,1與2的值需要嚴格一致,否則會造成矩陣運算錯誤,提示計算矩陣維數不一致錯誤信息。

過程:

      1、經緯向維數值1計算公式

            緯向維數:lat_steps = int(round((max_lat - min_lat)/grid_size,1)) +1

            經向維數:lon_steps = int(round((max_lon - min_lon)/grid_size,1)) +1

            此處假設經緯向網格間距一致,均爲grid_size值

            採向round取小數1位,防止浮點計算誤差,採用int方式取整,亦可用math.ceil,math.floor取整,方式不影響結果

            經向計算維數存在一些複雜性,因爲涉及到跨越日經線或零度線的問題。

            如經向值域爲(-180,180],則需考慮跨越日經線,如經向範圍爲:170~-160,30度的範圍,

                       此時:max_lon = -160,min_lon = 170,顯然:min_lon > max_lon。

                       則經向維數:lon_steps = int(round((max_lon + 360 - min_lon)/grid_size,1)) + 1

            經向值域爲(0, 360],則需考慮跨越零度經線(格林威治線),計算方式一致。

     2、準備總維數:

           lats = len(data.variables['lat']

           lons = len(data.variables['lon']

     2、切片取值方法

           切片取值基本方法:[起始序號值:起始序號值+切片維數值]

           需分別計算起始序號值與切片維數值。

           緯向計算:

                     st_lat_index = max(math.floor((min_lat - nc_min_lat)/grid_size),0)    # st_lat爲區域起始點,nc_min_lat爲文件的經向起始點

                     lat_steps = min(int(round((max_lat - min_lat)/grid_size,1)) +1,lats)    # 與之前的計算保持一致

                     rdata = data.variables[feature][...,  start_lat_index:start_lat_index+lat_steps, ...] 

           經向計算:

                  如果不考慮跨越日經線,計算方式完全一致,但跨越日經線帶來諸多麻煩事。

                  st_lon_index = max(math.floor((st_lon - min_lon)/grid_size),0)           #起始序號,與緯向一致

                  if min_lon > max_lon:                                                             #跨越日經線,策略:分段取值,再拼接,故需分別求出                                                                                            #兩切片維數值,同時確保兩段維數總和與之前計算的經向維數值一致。

                        lon_steps = min(int(round((max_lon + 360 - min_lon)/grid_size,1)) + 1, lons)
                        lon_steps1 = lons - start_lon_index                                 #用經向總維數 - 起始序號
                        lon_steps2 = lon_steps - lon_steps1

                        rdata1 = data.variables[feature][..., ..., start_lon_index:]

                        rdata2 = data.variables[feature][..., ..., : lon_steps2]

                        rdata=np.concatenate((rdata1,rdata2), axis=2)               # axis = 1/2根據實際情況定
                 else:                                                                                        #簡單模式
                        lon_steps = int(round((max_lon-min_lon)/grid_size,1)) + 1

                        rdata = data.variables[feature][..., ..., start_lon_index:start_lon_index+lon_steps]

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章