import expectexception
# 若沒有安裝則需要在conda的base環境中運作下面的代碼進行安裝
# pip install ExpectException
import numpy as np
import xarray as xr
from matplotlib import pyplot as plt
複制
示例資料
首先我們先導入所需的資料,本次使用的是經擴充重構的海表面溫度 v5 資料集(Extended Reconstructed Sea Surface Temperature, abbr. ERSST)。這個資料集可追溯到 1854 年的海表面溫度,并被廣泛使用。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICMyYTMvw1dvwlMvwlM3VWaWV2Zh1Wa-cmbw5CNqZmaz5GOqF3cvw1MxYTO4kTNtUGall3LcVmdhNXLwRHdo9CXt92YucWbpRWdvx2Yx5yazF2Lc9CX6MHc0RHaiojIsJye.png)
ERSST v5
下載下傳完畢資料後,我們利用
.open_dataset
函數導入 NetCDF 資料
path = "...\\sst.mnmean.nc"
# 删除一些不必要的變量
ds = xr.open_dataset(path, drop_variables=["time_bnds"])
# 提取1960年~2018年的資料
ds = ds.sel(time=slice("1960", "2018")).load()
ds
複制
ds
下面我們來做一下資料的基本制圖,通過圖形來檢查下載下傳資料的正确性。
ds.sst.isel(time=0).plot(vmin=-2, vmax=30)
複制
ds.sst.isel(time=0).plot(vmin=-2, vmax=30)
上述代碼選取了時間次元第一個的變量 sst,同時通過
vmin
和
vmax
定義色标的繪制變量數值範圍為-2 至 30. 假如我們縮小這個範圍,縮小至 20 至 30,我們可以得到以下的圖像。
ds.sst.isel(time=0).plot(vmin=20, vmax=30)
複制
ds.sst.isel(time=0).plot(vmin=20, vmax=30)
基本計算
xarray 的 DataArray 和 DataSet 對象可以無縫地使用計算操作符(如
+
,
-
,
*
,
/
)和 numpy 數組函數。
下面我們将上述海溫資料的攝氏溫度改寫為開爾文溫度為例說明上述問題。
兩者溫度轉化關系:開氏度 = 攝氏度 + 273.15
sst_kelvin = ds.sst + 273.15
sst_kelvin
複制
sst_kelvin
可以發現再進行計算操作後,資料集的次元和坐标都沒有發生變化。
需注意的是,許多導入的 xarray 資料集存在機關(units)屬性,這些屬性可用于繪圖,目前獨立于 xarray 項目進行開發的包pint[1]可以實作對機關的完全感覺并進行轉換。
下面我們來嘗試一下用更為複雜的函數進行計算。
假設轉為開爾文溫度的公式如下所示
f(\theta) = 0.5 \ln (\theta^2)
則可以編寫以下代碼
f = 0.5 * np.log(sst_kelvin ** 2)
f
複制
f
注意到
**
在 python 中代表乘方,此處
** 2
代表平方。
apply_ufunc 函數的使用
上面可以調用
np.log(ds)
并使其在 xarray 中“正常工作”是非常幸運的,因為并非所有的庫都能直接在 xarray 中正常工作。
numpy
相關的數學函數均可以直接在 xarray 中直接運算。
我們以一個執行個體來開始下面的内容:用于海水熱力學領域的Gibbs 海水工具包[2]。這個包提供了對 numpy 數組進行操作的 ufunc。
import gsw
# 若沒有安裝則需要在conda的base環境中運作下面的代碼進行安裝
# pip install gsw
複制
比如我們需要進行将上述資料的 IPTS-68 溫度轉換為 ITS-90 溫度。
國際計量委員會決定從 1990 年 1 月 1 日起采用新的溫度标準——“1909 年國際溫度刻度”(簡稱 ITS-90) , 這次溫度标準修訂的主要目的是為了解決以前采用的溫度标準 IPTS-68 存在的問題, 使溫度标準更準确地反映熱力學溫度, 提高溫度标準的複現性。這次溫度标準的修訂, 不是溫度機關的變更,是溫度标準的實作法、維持法的變更。(新的國際溫度标準 ITS-90 簡介,戚棟,1991)
我們先來看一下
gsw.t90_from_t68
函數的介紹
gsw.t90_from_t68?
複制
gsw.t90_from_t68?
同樣的内容也可在網站上查詢到
http://www.teos-10.org/pubs/gsw/html/gsw_t90_from_t68.html
複制
類似于上面的
np.log
函數,我們可以直接将 xarray 的 DataArray 對象放在函數括号裡。
gsw.t90_from_t68(ds.sst)
複制
gsw.t90_from_t68(ds.sst)
當然也可以使用
xr.apply_ufunc
函數對于數組中的每個元素進行
gsw.t90_from_t68
操作。這對于一些不能直接應用于 xarray 對象的函數是非常便捷的。
xr.apply_ufunc(gsw.t90_from_t68, ds.sst)
複制
xr.apply_ufunc(gsw.t90_from_t68, ds.sst)
apply_ufunc
函數功能強大,有很多可選參數以便進行複雜操作。更多可查閱Xarray docs[3]。
參考資料
[1]
pint: https://pint.readthedocs.io/en/0.16.1/
[2]
Gibbs海水工具包: https://teos-10.github.io/GSW-Python/
[3]
Xarray docs: http://xarray.pydata.org/en/latest/generated/xarray.apply_ufunc.html
注:本文基于Xarray Tutorials進行改寫,遵循Apache-2.0 License
https://github.com/xarray-contrib/xarray-tutorial