2
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

MetPyの単位変換

Last updated at Posted at 2022-10-10

はじめに

MetPyという気象系Pythonライブラリは,'unit-aware calculations'(単位を陽に定義する計算)の精神に基づき作成されており,事前に変数の単位を定義しておけば単位変換を”よろしく”やってくれるので,つまらない計算ミスを減らすことができる(と思っている).

単位変換を簡単にできるのだが,データのクラスによって使い方が異なり困惑したので,まとめておく.

結論から書くと,pint.quantityは.to()というメソッドを,xarary.DataArrayには.metpy.convert_units()というメソッドを使う.

unitsの使い方とpint.quantity

metpy自体はpipやcondaやmacportsで簡単にインストールできる.(Install Guide - Metpy User Guide)

metpy.units.unitsをインポートする.fromを使うことが多い気がする.
xarrayも使う.

from metpy.units import units 
import xarray as xr

単位は掛け算*で使う

a = 0. * units.degC

a
0.0 <Unit('degree_Celsius')>

type(a)
pint.quantity.build_quantity_class.<locals>.Quantity

上記により,aに0.0セルシウス度を定義した.pint.quantityというクラスらしい.

unitsは属性的な使い方の他に,メソッド的な使い方もできる

b = 0. * units('degC')

a == b
Ture

dir(units)で使える単位の一覧が出てくるが,公式のリストは存在しない(見つけてないだけ?)
ものによってはメソッド的な使い方しかできない(units('m/s^2')とか).

xarray.DataArrayに丸ごと単位をつけることもできる.xarray.Datasetには単位を定義できない(過去の記事

ds = xr.open_dataset('temperature_sample.nc')
da = ds['temperature']
da_u = da * units.kelvin

da_u
(上部省略)
  [[194.72113 194.768   194.78363 ... 193.59613 193.59613 193.59613]
   [194.68988 194.72113 194.768   ... 193.65863 193.62738 193.62738]
   [194.65863 194.7055  194.81488 ... 193.7055  193.67426 193.67426]
   ...
   [221.90863 221.92426 221.98676 ... 224.12738 224.143   224.143  ]
   [221.98676 222.00238 222.03363 ... 224.11176 224.12738 224.143  ]
   [222.06488 222.06488 222.09613 ... 224.09613 224.12738 224.143  ]]]], 'kelvin')>
Coordinates:
  * time     (time) datetime64[ns] 2017-12-31T15:00:00 ... 2018-02-28T09:00:00
  * lev      (lev) int64 1000 975 950 925 900 850 ... 400 300 250 200 150 100
  * lon      (lon) float64 120.0 120.1 120.2 120.4 ... 149.6 149.8 149.9 150.0
  * lat      (lat) float64 22.4 22.5 22.6 22.7 22.8 ... 47.2 47.3 47.4 47.5 47.6

しかし,これはpint.quantityではない

type(da_u)
xarray.core.dataarray.DataArray

単位変換

pint.quantityは.to()というメソッドを,xarary.DataArrayには.metpy.convert_units()というメソッドを使う.それぞれのクラスの違いに対応していると思われる.

aをセルシウス度からKelvinに,da_uは逆にKelvinからセルシウス度に変換してみる.

a.to('kelvin')
273.15 <Unit('kelvin')>

da_u.metpy.convert_units('degC')
(途中省略)
  [[-7.8428864e+01 -7.8381989e+01 -7.8366364e+01 ... -7.9553864e+01
    -7.9553864e+01 -7.9553864e+01]
   [-7.8460114e+01 -7.8428864e+01 -7.8381989e+01 ... -7.9491364e+01
    -7.9522614e+01 -7.9522614e+01]
   [-7.8491364e+01 -7.8444489e+01 -7.8335114e+01 ... -7.9444489e+01
    -7.9475739e+01 -7.9475739e+01]
   ...
   [-5.1241364e+01 -5.1225739e+01 -5.1163239e+01 ... -4.9022614e+01
    -4.9006989e+01 -4.9006989e+01]
   [-5.1163239e+01 -5.1147614e+01 -5.1116364e+01 ... -4.9038239e+01
    -4.9022614e+01 -4.9006989e+01]
   [-5.1085114e+01 -5.1085114e+01 -5.1053864e+01 ... -4.9053864e+01
    -4.9022614e+01 -4.9006989e+01]]]], 'degree_Celsius')>
Coordinates:
  * time     (time) datetime64[ns] 2017-12-31T15:00:00 ... 2018-02-28T09:00:00
  * lev      (lev) int64 1000 975 950 925 900 850 ... 400 300 250 200 150 100
  * lon      (lon) float64 120.0 120.1 120.2 120.4 ... 149.6 149.8 149.9 150.0
  * lat      (lat) float64 22.4 22.5 22.6 22.7 22.8 ... 47.2 47.3 47.4 47.5 47.6

ちゃんとaはKelvinに,da_uはセルシウス度に変換されていることが分かる.
(da_uは極東域の100 hPa(成層圏下部)の気温なので,-70~-50℃という値)

.ito()でオブジェクト指向的?にaの単位を書き換える.(.to()は多分コピーを返す)

a.ito('kelvin')
a
273.15 <Unit('kelvin')>

参考文献

Converting units - Working With Units - Metpy Tutorials

Units - xarray with MetPy Tutorial - Metpy Tutorials

2
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?