2. 熱帯赤道上空東西風のEOF解析(QBOのindex化)

◆ データの読み込み(1960-2020年) :

In [1]:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from mpl_toolkits.mplot3d import Axes3D
import xarray as xr
import datetime

from pandas.plotting import register_matplotlib_converters #これを描かないと警告文がでる(オマジナイ)
register_matplotlib_converters()
In [2]:
# データの読み込み
# 以下を参考にしました
# https://arg.usask.ca/docs/LOTUS_regression/_modules/LOTUS_regression/predictors/download.html

file = "data/qbo_1953_2021.dat"
#--> "data/dd/qbo_1953_2021.dat"に変更のこと

def date_parser(s):
        s = int(s)
        return datetime.datetime(2000 + s // 100 if (s // 100) < 50 else 1900 + s // 100, s % 100, 1)

dataORG = pd.read_fwf(file,
                       skiprows=92, header=None,
                       colspecs=[(0, 5), (6, 10), (12, 16), (19, 23), (26, 30), (33, 37), (40, 44), (47, 51), (54, 58)],
                         delim_whitespace=True, index_col=1, parse_dates=True, date_parser=date_parser,
                         names=['station', 'month', '70', '50', '40', '30', '20', '15', '10'])
#dataORG.index = dataORG.index.to_period(freq='M')

#最初の方(1950年代は歯抜けが多いので、skiprows=92として読み飛ばしています)


data_sub = dataORG.loc['1960-01':'2020-12',:].copy()
data_sub.drop('station', axis=1, inplace=True)
data_sub /= 10.0 # units: m/s に変換


print(data_sub.head()) #列方向は気圧座標が入っている(高度に換算すると 70 hPa~20 km, 10 hPa~ 30 km, に相当)
             70   50   40    30    20    15    10
month                                            
1960-01-01  6.5  5.0  3.0  -0.2  -1.8  -7.4 -14.0
1960-02-01  2.0  6.7  5.4  -1.8  -5.1  -9.0 -17.0
1960-03-01  5.0  7.0  5.0  -4.6  -8.3 -11.0 -19.0
1960-04-01  6.5  6.0  3.0 -12.4 -15.2 -16.0 -20.0
1960-05-01  8.0  6.9 -0.5 -18.2 -17.0 -18.0 -23.0

◆ Deseasonalization(季節変化の除去)について:

  • 年々変動に注目するので、季節変化成分を予め取り除いておく。

  • 色々やり方はあるが、各月でコンポジットを取って月平均の東西風(の高度分布)を算出し、オリジナルデータから差し引くのが簡単(他にも調和関数で季節変化を定義して取り除く方法などがある)。

  • コンポジットについては、例えば演習DBの内容を思い出してください(演習DB [2.時系列データの解析] )


◆ 解析にあたってのヒント・補足

  • 軸データデータ行列は以下のように取り出せる(前回の復習):

    • data_sub.index: 行方向のインデックス(上のデータの場合、時刻)

    • data_sub.columns: 列方向のインデックス(上のデータの場合、気圧座標)

    • data_sub.values: データ行列(軸は落とす)

  • 【Fig.3】 行列の積を計算する際に、縦ベクトル横ベクトルを区別したいときがある。uを大きさnの配列とすると:

    • uh = np.reshape(u, (1,n)):横ベクトルにする
    • uv = np.reshape(u, (n,1)):縦ベクトルにする

◆ 描画方法のヒント・補足

  • Fig.1: EOF1 & EOF2 を 気圧座標(縦軸)の関数として描画
  • Fig.2: PC1 & PC2 を 時刻(横軸)の関数として描画
  • Fig.3: 横軸:時刻(x)、縦軸(y):気圧座標として、東西風速(z)をコンター表示

    • コンター(塗りつぶし)メソッド: ax.contourf(x,y,z) (z = z(y, x))
  • Fig.4: PC1 (横軸)➖ PC2(縦軸)の散布図

    • 散布図を描くメソッド: ax.scatter(x,y,....)
  • Fig.5: 横軸: 緯度(x)、縦軸(y):気圧座標として、回帰係数をコンター表示


◆ 発展課題(Fig. 5)について

  • 月平均東西風データはdata/ncep.reanalysis.derived/pressure/uwnd.mon.mean.ncを使用。

  • データの読み込み・切り出しは、演習DBの内容を参考にしてください(演習DB[3.全球大気再解析データの解析] )

  • 以下、データの読み込み例(の一部)を示す:

In [3]:
file = "Fortran/data/uwnd.mon.mean.nc" 
#月平均東西風データを指定
#"data/ncep.reanalysis.derived/pressure/"以下に変更

data = xr.open_dataset(file)

print(data)
<xarray.Dataset>
Dimensions:  (lat: 73, level: 17, lon: 144, time: 855)
Coordinates:
  * level    (level) float32 1000.0 925.0 850.0 700.0 ... 50.0 30.0 20.0 10.0
  * lat      (lat) float32 90.0 87.5 85.0 82.5 80.0 ... -82.5 -85.0 -87.5 -90.0
  * lon      (lon) float32 0.0 2.5 5.0 7.5 10.0 ... 350.0 352.5 355.0 357.5
  * time     (time) datetime64[ns] 1948-01-01 1948-02-01 ... 2019-03-01
Data variables:
    uwnd     (time, level, lat, lon) float32 ...
Attributes:
    title:          monthly mean u wind from the NCEP Reanalysis
    description:    Data from NCEP initialized reanalysis (4x/day).  These ar...
    platform:       Model
    Conventions:    COARDS
    NCO:            20121012
    history:        Mon Jul  5 22:36:33 1999: ncrcat uwnd.mon.mean.nc /Datase...
    References:     http://www.esrl.noaa.gov/psd/data/gridded/data.ncep.reana...
    dataset_title:  NCEP-NCAR Reanalysis 1
In [4]:
uwnd = data['uwnd'] #東西風(uwnd)読み込み。この段階ではまだ軸が付いているので、以下解析の為にそれらを分離する

plevel = uwnd['level'].values #軸データ:気圧座標
lat = uwnd['lat'].values # 軸データ:緯度

print('Pressure levels = ', plevel)
print('Latitudes = ',lat)

uwnd_v = uwnd.values #データ行列(東西風の値のみ)
Pressure levels =  [1000.  925.  850.  700.  600.  500.  400.  300.  250.  200.  150.  100.
   70.   50.   30.   20.   10.]
Latitudes =  [ 90.   87.5  85.   82.5  80.   77.5  75.   72.5  70.   67.5  65.   62.5
  60.   57.5  55.   52.5  50.   47.5  45.   42.5  40.   37.5  35.   32.5
  30.   27.5  25.   22.5  20.   17.5  15.   12.5  10.    7.5   5.    2.5
   0.   -2.5  -5.   -7.5 -10.  -12.5 -15.  -17.5 -20.  -22.5 -25.  -27.5
 -30.  -32.5 -35.  -37.5 -40.  -42.5 -45.  -47.5 -50.  -52.5 -55.  -57.5
 -60.  -62.5 -65.  -67.5 -70.  -72.5 -75.  -77.5 -80.  -82.5 -85.  -87.5
 -90. ]
In [ ]: