2.2. pandas と xarray¶
Pythonの有名なデータ解析ライブラリに pandas [1] があります。 pandas は、汎用的なデータ解析に関するインターフェースを提供するものです。 その注目すべき特徴の1つが、座標付きのデータ(labeled data)をうまく扱うことができる点です。
例えば時系列データを扱うとき、時間データと計測値の2つを保持しておく必要が有ります。
ある時間領域を切り出す時は同じ操作を両データに適用する必要が有りますし、
またある時刻での計測値を知りたいときは、時間データから対応する要素番号を探しだし、
計測データに対してその要素番号を用いてアクセスすることが必要です。
これらの操作は前節で紹介した np.ndarray
でももちろん可能ですが、
毎回各自がコーディングしていると時間がかかるだけでなく、ミスの元になります。
このようなデータ解析に必要な汎用的な操作をまとめてインターフェースとして提供しているのがpandasです (日付関連の操作や、欠損値に対する操作、複数のデータをまとめる操作など、他にも多様な便利機能がまとめられています)。 pandasはアンケート結果や株価の推移など、一般のデータ解析に広く用いられています。
一方でプラズマ計測データなど多くの物理データは、複数の座標軸を持ちます。 例えば、電子温度分布の時間変化データは、計測位置と時間という2つの軸を持つことになります。 ある時間における分布が知りたかったり、ある位置の温度の時間変化が知りたかったりします。 しかし pandas は1次元のデータ(表に表すことのできるデータ)しか扱うことができません。 xarray [2] [3] は、 pandas を多次元データに拡張したもので、地球科学研究分野から生まれたものです。 まだ新しいライブラリですが、 他種類の多次元データを扱うことの多いプラズマ研究でも有用だと思われますので、ここで紹介します。
[1] | https://pandas.pydata.org/ |
[2] | https://xarray.pydata.org/ |
[3] | Hoyer, S. & Hamman, J., (2017). xarray: N-D labeled Arrays and Datasets in Python. Journal of Open Research Software. 5(1), p.10 |
2.2.1. xarray のインストール¶
Anaconda distribution を用いて Python 開発環境を整えた人は
conda install xarray
としてください。Native の Python を用いている人は
pip install xarray
とするとよいでしょう。
2.2.2. xarray の使い方¶
ここでは、実際のプラズマ実験データを使ってxarray の使い方を説明します。 核融合科学研究所で計測された トムソン散乱による電子温度・密度の結果を読み込みましょう。 ファイルの読み込みプログラムやいくつかの計測データの例を https://github.com/plasmalib/python_tutorial/data に用意しました。 これを data フォルダに保存して以下のように読み込みましょう。
In [1]: import xarray as xr # xarray は xr と省略するのが一般的なようです
In [2]: import sys
In [3]: sys.path.append('data')
In [4]: import eg # 読み込みプログラムも data/eg.py として保存しておいてください
In [5]: thomson = eg.load('data/thomson@115500.dat') # thomson データの読み込み
In [6]: print(thomson)
<xarray.Dataset>
Dimensions: (R: 140, Time: 246)
Coordinates:
* Time (Time) float64 0.0 33.0 66.0 100.0 133.0 166.0 200.0 233.0 ...
* R (R) float64 2.409e+03 2.436e+03 2.463e+03 2.49e+03 ...
ShotNo int64 115500
Data variables:
Te (Time, R) float64 90.0 20.0 22.0 83.0 46.0 54.0 27.0 0.0 ...
dTe (Time, R) float64 1e+05 1e+05 1e+05 1e+05 1e+05 1e+05 1e+05 ...
n_e (Time, R) float64 0.0 0.0 0.0 0.0 0.0 0.0 1.0 30.0 0.0 3.0 ...
dn_e (Time, R) float64 2.0 2.0 2.0 2.0 2.0 2.0 2.0 243.0 1.0 ...
laser (Time, R) float64 913.0 913.0 913.0 913.0 913.0 913.0 913.0 ...
lasernumber (Time, R) float64 2.0 2.0 2.0 2.0 2.0 2.0 2.0 2.0 2.0 2.0 ...
Attributes:
NAME: THOMSON
Date: 11/19/201215:24
まず、print
文を用いた時の出力が綺麗に整形されていることがわかります。
Dimensions
の行に (R: 140, Time: 246)
とあるのは、
含まれる変数は、2つの次元 Time
と R
に依存するということ、
それらの大きさがそれぞれ140、246であることを示しています。
Coordinates
セクションには、それら軸の座標の値が表示されています。
LHDのThomson散乱では、電子温度や密度やその推定誤差などが得られますが、それらが
Data variables
セクションに含まれています。
Data variables
セクションの例えば Te の列には (Time, R) とありますが、
これはこの変数が Time
と R
に依存するということを示しています。
各 Coordinates
や Data variables
にアクセスするには、辞書型のように
['Te']
というようにすることでアクセスできます。
In [7]: thomson['Te']
Out[7]:
<xarray.DataArray 'Te' (Time: 246, R: 140)>
array([[ 90., 20., 22., ..., 0., 82., 1796.],
[ 6., 17., 10., ..., 19., 26., 13.],
[ 7., 0., 40., ..., 14., 6., 57.],
...,
[ 6., 133., 0., ..., 43., 40., 23.],
[ 10., 9., 48., ..., 70., 53., 58.],
[ 7., 39., 14., ..., 26., 0., 15.]])
Coordinates:
* Time (Time) float64 0.0 33.0 66.0 100.0 133.0 166.0 200.0 233.0 ...
* R (R) float64 2.409e+03 2.436e+03 2.463e+03 2.49e+03 2.517e+03 ...
ShotNo int64 115500
Attributes:
Unit: eV
このように1種類のデータを選んでも、同時に座標情報が付随していることがわかります。
ラベルを用いたインデクシング¶
Coordinate
セクションに Time, R
が表示されているように、このデータには座標情報も付属します。
.sel
メソッドを用いることで、座標軸を元に要素を選択することができます。
In [8]: thomson.sel(Time=6800.0, method='nearest')
Out[8]:
<xarray.Dataset>
Dimensions: (R: 140)
Coordinates:
Time float64 6.8e+03
* R (R) float64 2.409e+03 2.436e+03 2.463e+03 2.49e+03 ...
ShotNo int64 115500
Data variables:
Te (R) float64 6.0 13.0 7.0 18.0 9.0 34.0 5.0 15.0 799.0 167.0 ...
dTe (R) float64 9.0 5.0 1e+05 29.0 0.0 12.0 1.0 2.0 134.0 0.0 ...
n_e (R) float64 -4.0 -13.0 1.0 -9.0 -3.257e+04 19.0 49.0 91.0 ...
dn_e (R) float64 2.0 1.0 2.0 3.0 121.0 3.0 5.0 6.0 1.0 59.0 8.0 ...
laser (R) float64 912.0 912.0 912.0 912.0 912.0 912.0 912.0 912.0 ...
lasernumber (R) float64 2.0 2.0 2.0 2.0 2.0 2.0 2.0 2.0 2.0 2.0 2.0 2.0 ...
Attributes:
NAME: THOMSON
Date: 11/19/201215:24
ここでは、 Time
軸が 6800.0 に最も近い計測値を取得しています。
Dimensions
の行から Time
が消えて (R: 140)
だけになったことからもわかるように、
全ての計測値を一度にインデクシングしていることがわかります。
ある時刻の結果だけグラフに描きたい、ということもよくありますが、
その場合も、 .sel
メソッドを用いることで1行で実現できます。
In [9]: plt.plot(thomson['R'], thomson['Te'].sel(Time=6800.0, method='nearest'))
Out[9]: [<matplotlib.lines.Line2D at 0x7f58ff3afda0>]
In [10]: plt.xlabel('$R$ (m)')