python寫入二維netCDF文件(txt轉nc文件)


netCDF文件后綴名是.nc,是一種二進制的網格文件,無法直接打開,下面給出基於python的netCDF文件生成的腳本。

(該程序目前已發布更新版本,鏈接是https://www.cnblogs.com/liangxuran/p/13659283.html

輸入數據說明:

數據為31°N-40°N,130°E-142°E區域表層的地震波速,網格分布大小不均勻。數據存儲在txt文件中,分為三列,無表頭。

部分數據記錄見下圖,第一列是經度,第二列是維度,第三列是波速擾動值%

 

過程與代碼 

為了將其生成均勻網格的二維nc文件,我們需要1.文件讀取,2.數據插值,3.寫入nc文件。

 1 '''
 2 program: ncdata.py
 3 goal:    interpolate txt data and generate grd file
 4 input:   vp1_02.txt
 5 output:  vp1_03.nc
 6 author:  Liang Xuran
 7 e-mail:  xuranliang@hotmail.com
 8 time:    2020.08.23
 9 '''
10 import netCDF4 as nc
11 import pandas as pd
12 import numpy as np
13 import copy
14 
15 file_txt = "vp1_02.txt"#txt文件位置
16 file_nc  = "vp1_03.nc" #nc文件輸出位置
17 npa = 37  #緯向格點數(uninpolate)
18 nra = 45  #經向格點數(uninpolate)
19 npx = 180 #緯向格點數(inpolate)
20 nrx = 240 #經向格點數(inpolate)
21 
22 #使用Dataset創建nc文件
23 nc_pro = nc.Dataset("vp1_03.nc", 'w', format = 'NETCDF4')
24 
25 #命名nc文件變量,None為自由維度,name='pna',size=npa
26 nc_pro.createDimension('pna',npx+1)
27 nc_pro.createDimension('rna',nrx+1)
28 
29 #設置nc文件中變量類型,這里使用的是float64
30 pna = nc_pro.createVariable('pna',np.float64,('pna',))
31 rna = nc_pro.createVariable('rna',np.float64,('rna',))
32 dv  = nc_pro.createVariable('dv',np.float64,('pna','rna'))
33 
34 #定義變量單位
35 pna.units = 'degree'
36 rna.units = 'degree'
37 dv.units  = '%'
38 
39 #使用panda中的read_csv讀取txt文件
40 #type(nc_data)=<class 'pandas.core.frame.DataFrame'>
41 nc_data=pd.read_csv("vp1_02.txt",delim_whitespace=True,names='rpv')
42 
43 #插值操作:精度0.05degree,范圍rna=130:142;pna=31:40
44 pnx = nc_data['p'].values[0:1665:nra]
45 rnx = nc_data['r'].values[0:nra]
46 dvx = nc_data['v'].values.reshape(npa,nra)
47 rx  = np.linspace(130,142,241)
48 px  = np.linspace(31,40,181)
49 vx  = np.full([181,241],np.nan)
50 for i in range(npa):
51     for j in range(nra):
52         m = int(round((pnx[i]-pnx[0])/0.05))
53         n = int(round((rnx[j]-rnx[0])/0.05))
54         vx[m,n]=dvx[i,j]
55 #縱向插值,從vx[181,241]獲得中間量dv_inpolate1[181,241]
56 nc_v_uninpo  = pd.DataFrame(vx) #transfer np.array into pandas.DataFrame
57 nc_v_inpo1   = nc_v_uninpo.interpolate() #pandas.DataFrame interpolate
58 dv_inpolate1 = nc_v_inpo1.values #tansfer pandas.DataFrame into np.array
59 #橫向插值,從dv_inpolate1[181,241]獲得中間量dv_inpolate2[181,241]
60 nc_v_inpo    = pd.DataFrame(dv_inpolate1.T)
61 nc_v_inpo2   = nc_v_inpo.interpolate()
62 dv_inpolate2 = nc_v_inpo2.values.T
63 
64 #將數值輸入到nc文件中,input must be np.array
65 nc_pro.variables['pna'][:]  = px
66 nc_pro.variables['rna'][:]  = rx
67 nc_pro.variables['dv'][:,:] = dv_inpolate2[:,:]
68 #為避免內存的占用,寫完一個關閉一個
69 nc_pro.close()
70     

 

踩坑指南:

1.文件路徑最好寫相對路徑,第15-16行寫絕對路徑/mnt/f/research/vp1_02.txt會出現報錯。

2.插值前后格點數量有所擴充,由於經緯度的變量檢索是從0開始的,因此,26-27行創建變量的維度需要加1,也可以定位None,代表自由維度。

3.元組只有一個元素時,需要在括號末尾加“,”,例如30-31行。

4.用pandas.read_csv讀取文件時,第41行,默認數據之間時用“,”逗號連接的,需要修改默認值delim_whitespace代表用空格連接。names代表每一列的元素名稱。

5.二維數據pandas.DataFrame進行賦值/輸出內容時,需要使用其values屬性,例如44-46行。在插值過程中,也需要將numpy.array矩陣轉為pandas.DataFrame網格后進行,例如55-62行。

6.nc文件的變量被賦值的時候,只接受numpy.array數據,例如65-67行;二維的numpy.array數據索引是一個中括號而不是兩個中括號[0:181,0:241],例如54行和67行。

7.python的浮點型數據和整形數據加減運算的時候要小心,例如52-53行計算mn的時候,出現了以下現象:

8.關於變量的索引和插值前后數據的對比檢驗。可以參考下圖:

 

檢驗未插值部分的數據,選擇34.25°N-34.30°N,134.80°E-134.85°E區域: dvx[10:12,12:14]  vx[65:67,96:98]

檢驗已插值部分的數據,選擇33.2°N-33.4°N,136.6°E-136.8°E的區域: dvx[2:4,41:43]  vx[4:9,132:137]

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM