暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

数据处理 | 经验正交函数(EOF)与旋转经验正交函数(REOF)

气海无涯 2021-08-22
3385

点击下方公众号,回复资料,收获惊喜

导入模块

from pyEOF import *
import xarray as xr
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

Warning: ecCodes 2.22.0 or higher is recommended. You are running version 2.21.0

定义绘图函数

# create a function for visualization convenience
def visualization(da, pcs, eofs_da, evf):
    fig = plt.figure(figsize=(1212))

    ax = fig.add_subplot(n+121)
    da.mean(dim=["lat""lon"]).plot(ax=ax)
    ax.set_title("average air temp")

    ax = fig.add_subplot(n+122)
    da.mean(dim="time").plot(ax=ax)
    ax.set_title("average air temp")

    for i in range(1, n+1):
        pc_i = pcs["PC"+str(i)].to_xarray()
        eof_i = eofs_da.sel(EOF=i)["air"]
        frac = str(np.array(evf[i-1]*100).round(2))

        ax = fig.add_subplot(n+12, i*2+1)
        pc_i.plot(ax=ax)
        ax.set_title("PC"+str(i)+" ("+frac+"%)")

        ax = fig.add_subplot(n+12, i*2+2)
        eof_i.plot(ax=ax,
                   vmin=-0.75, vmax=0.75, cmap="RdBu_r",
                   cbar_kwargs={'label'""})
        ax.set_title("EOF"+str(i)+" ("+frac+"%)")

    plt.tight_layout()
    plt.show()


读取气温数据

# load the DataArray
da = xr.tutorial.open_dataset('air_temperature')["air"]
print(da)

# create a mask
mask = da.sel(time=da.time[0])
mask = mask.where(mask<250).isnull().drop("time")

# get the DataArray with mask
da = da.where(mask)
da.sel(time=da.time[99]).plot()
plt.show()

<xarray.DataArray 'air' (time: 2920, lat: 25, lon: 53)>
[3869000 values with dtype=float32]
Coordinates:
* lat (lat) float32 75.0 72.5 70.0 67.5 65.0 ... 25.0 22.5 20.0 17.5 15.0
* lon (lon) float32 200.0 202.5 205.0 207.5 ... 322.5 325.0 327.5 330.0
* time (time) datetime64[ns] 2013-01-01 ... 2014-12-31T18:00:00
Attributes:
long_name: 4xDaily Air temperature at sigma level 995
units: degK
precision: 2
GRIB_id: 11
GRIB_name: TMP
var_desc: Air temperature
dataset: NMC Reanalysis
level_desc: Surface
statistic: Individual Obs
parent_stat: Other
actual_range: [185.16 322.1 ]

# convert DataArray to DataFrame
df = da.to_dataframe().reset_index() # get df from da
display(df.head(5))
print("DataFrame Shape:",df.shape)


timelatlonair
02013-01-0175.0200.0NaN
12013-01-0175.0202.5NaN
22013-01-0175.0205.0NaN
32013-01-0175.0207.5NaN
42013-01-0175.0210.0NaN
DataFrame Shape: (3869000, 4)

# reshape the dataframe to be [time, space]
df_data = get_time_space(df, time_dim = "time", lumped_space_dims = ["lat","lon"])
display(df_data.head(5))
print("DataFrame Shape:",df_data.shape)


air
lat75.0...15.0
lon200.0202.5205.0207.5210.0212.5215.0217.5220.0222.5...307.5310.0312.5315.0317.5320.0322.5325.0327.5330.0
time




















2013-01-01 00:00:00NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN...299.699982299.100006298.699982298.600006298.000000297.790009297.600006296.899994296.790009296.600006
2013-01-01 06:00:00NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN...299.290009298.600006298.199982298.100006297.500000297.100006296.899994296.399994296.399994296.600006
2013-01-01 12:00:00NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN...299.199982298.699982298.790009298.699982297.899994297.899994297.600006297.000000297.000000296.790009
2013-01-01 18:00:00NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN...300.000000299.399994299.100006299.100006298.500000298.600006298.199982297.790009298.000000297.899994
2013-01-02 00:00:00NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN...299.600006299.000000298.790009299.000000298.290009298.100006297.699982297.100006297.399994297.399994

5 rows × 1325 columns

DataFrame Shape: (2920, 1325)

REOF分解

n = 4
pca = df_eof(df_data,pca_type="varimax",n_components=n)

eofs = pca.eofs(s=2, n=n) # get eofs
eofs_da = eofs.stack(["lat","lon"]).to_xarray() # make it convenient for visualization
pcs = pca.pcs(s=2, n=n) # get pcs
evfs = pca.evf(n=n) # get variance fraction

# plot
visualization(da, pcs, eofs_da, evfs)

/home/lqy/anaconda3/lib/python3.8/site-packages/sklearn/utils/extmath.py:847: RuntimeWarning: invalid value encountered in true_divide
updated_mean = (last_sum + new_sum) / updated_sample_count
/home/lqy/anaconda3/lib/python3.8/site-packages/sklearn/utils/extmath.py:687: RuntimeWarning: Degrees of freedom <= 0 for slice.
result = op(x, *args, **kwargs, dtype=np.float64)

传统EOF分解

n = 4 # define the number of components

pca = df_eof(df_data) # implement EOF

eofs = pca.eofs(s=2, n=n) # get eofs
eofs_da = eofs.stack(["lat","lon"]).to_xarray() # make it convenient for visualization
pcs = pca.pcs(s=2, n=n) # get pcs
evfs = pca.evf(n=n) # get variance fraction

# plot
visualization(da, pcs, eofs_da, evfs)

/home/lqy/anaconda3/lib/python3.8/site-packages/sklearn/utils/extmath.py:847: RuntimeWarning: invalid value encountered in true_divide
updated_mean = (last_sum + new_sum) / updated_sample_count
/home/lqy/anaconda3/lib/python3.8/site-packages/sklearn/utils/extmath.py:687: RuntimeWarning: Degrees of freedom <= 0 for slice.
result = op(x, *args, **kwargs, dtype=np.float64)

eofs模块分解结果

from eofs.standard import Eof
from sklearn.preprocessing import StandardScaler
solver = Eof(StandardScaler().fit_transform(df_data.values))

s_pcs = pd.DataFrame(data=solver.pcs(npcs=4, pcscaling=2),
                     columns = pcs.columns,
                     index = pcs.index)


s_eofs = pd.DataFrame(data = solver.eofs(neofs=4, eofscaling=2),
                      columns = eofs.columns,
                      index = eofs.index)
s_eofs_da = s_eofs.stack(["lat","lon"]).to_xarray() # make it convenient for visualization

s_evfs = solver.varianceFraction(neigs=4)

# plot
visualization(da, s_pcs, s_eofs_da, s_evfs)

/home/lqy/anaconda3/lib/python3.8/site-packages/sklearn/utils/extmath.py:847: RuntimeWarning: invalid value encountered in true_divide
updated_mean = (last_sum + new_sum) / updated_sample_count
/home/lqy/anaconda3/lib/python3.8/site-packages/sklearn/utils/extmath.py:687: RuntimeWarning: Degrees of freedom <= 0 for slice.
result = op(x, *args, **kwargs, dtype=np.float64)

气象数据分析 | 经验正交分解EOF

2021-07-29

Monthly Weather Review主编教你写论文——几本气象写作好书推荐

2021-07-28

python爬取中央气象台台风网当前台风实况和预报数据

2021-07-27

Python可视化 | 基于CNN的台风云图的heatmap可视化

2021-07-26

大气科学Python图书比议

2021-07-26


数据处理·机器学习·可视化

行业资讯·学习资料


文章转载自气海无涯,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论