Python | SLP | EOF | 去除季节趋势

EOF & PC
EOF & PC

前言

在计算EOF(经验正交函数)之前去除季节循环是为了消除数据中的季节变化的影响,使得EOF能够更好地捕捉数据中的空间变化模式。如果不去除季节循环,季节性信号可能会在EOF中占据较大的比例,从而影响对其他空间模态的识别。通过去除季节循环,我们可以更准确地识别和分析数据中的长期趋势和非季节性变化。

数据来源


  • monthly mean of surface pressure
  • 2.5 ° x 2.5°
  • 1948-01-01 ~ 2023-12-01
  • 地址: http://apdrc.soest.hawaii.edu/las/v6/dataset?catitem=17027
<xarray.Dataset>
Dimensions:    (LON41_105: 65, LAT43_65: 23, TIME: 912, bnds: 2)
Coordinates:
  * LON41_105  (LON41_105) float64 100.0 102.5 105.0 107.5 ... 255.0 257.5 260.0
  * LAT43_65   (LAT43_65) float64 15.0 17.5 20.0 22.5 ... 62.5 65.0 67.5 70.0
  * TIME       (TIME) datetime64[ns] 1948-01-01 1948-02-01 ... 2023-12-01
Dimensions without coordinates: bnds
Data variables:
    TIME_bnds  (TIME, bnds) datetime64[ns] ...
    PRES       (TIME, LAT43_65, LON41_105) float32 ...
Attributes:
    history:      FERRET V6.5  31-Mar-24
    Conventions:  CF-1.0

基础概念

EOF(Empirical Orthogonal Function)

EOF是一种用于分析空间场景的统计方法。它可以提取数据中的主要空间变化模式,即数据的主要空间结构。 在EOF分析中,EOFs是空间模式,它们代表了数据在空间上的主要变化模式。通常,EOFs按照其对数据方差的贡献程度进行排序,因此,EOF1代表数据中的主要空间变化模式,EOF2代表次要的空间变化模式,依此类推。

EOFs通常是空间场景的正交函数,即它们之间是相互独立的。这意味着每个EOF捕获数据中不同的空间变化模式,不会出现重叠。

通过观察EOFs,可以了解数据中的主要空间结构,从而推断出数据的空间分布规律和特征。

PS : 个人理解EOF得到的第一模态,即在限定的空间区域内(比如说太平洋中部以及北部),以及在这一限定时间周期内(比如说从1970-2010年内),该空间区域内最显著、主导的空间 Pattern

PC(Principal Component)

PCEOF分析的另一个重要结果,它是每个时间步数据在EOF模式上的投影。换句话说,PC表示了数据随时间变化时,EOF空间模式的权重PC1通常表示数据中的主要时间变化模式,PC2表示次要的时间变化模式,以此类推。通常情况下,PC1会对应数据中的主要变化方向,即数据集的整体趋势或变化方向。

通过观察PC时间序列,可以了解数据在不同时间点上的变化规律,从而推断出数据的时间演变特征和趋势。

代码实现


from typing import Tuple
import os
import xarray as xr
import glob
import numpy as np
import cartopy.feature as cfeature
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
import cmaps
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import matplotlib.ticker as mticker
from eofs.standard import Eof
from matplotlib import ticker 
import cartopy.mpl.ticker              as ctk
# ================================================================================================
# Author: %(Jianpu)s | Affiliation: Hohai
# Email : %(email)s
# Last modified: 2024-04-03 12:28:06
# Filename: 
# Description: 
# =================================================================================================
# Your code continues here
  • 定义读取nc文件函数


def read_netcdf(path: str, time_min: str, time_max: str) -> xr.Dataset:
    """
    读取NetCDF文件并返回数据集对象。

    参数:
    path (str): NetCDF文件的路径。
    time_min (str): 起始时间,格式为'YYYY-MM-DD'。
    time_max (str): 结束时间,格式为'YYYY-MM-DD'。

    返回值:
    data (xarray.Dataset): 包含选择时间范围内数据的数据集对象。
    """

    data = xr.open_dataset(path).sel(TIME=slice(time_min, time_max))
    return data
  • 定义前处理函数,计算纬度权重、去除季节趋势、计算EOF和PC

计算纬度权重:

首先,通过 np.cos(np.deg2rad(lat)) 计算了每个纬度点的纬度值的余弦值,即 $cos(\text{纬度})$。然后,使用 np.sqrt(coslat) 对余弦值进行开方运算,得到了纬度权重。这样做的目的是因为地球在不同纬度上的面积并不相同,通过使用纬度权重,可以对数据进行加权,更准确地反映出不同纬度上的变化情况。

去除季节循环:

首先,获取数据的维度信息,包括时间维度(nt)、纬度维度(nlat)和经度维度(nlon)。然后,将数据按照时间、月份和网格点的顺序进行重塑,使得数据的形状变为 (月份, 年数, 网格点数)。接着,计算每个月份的平均值,得到了季节循环。然后,通过减去季节循环,得到了去除季节循环后的数据 pres_anom。这样做的目的是为了消除数据中的季节性变化,使得后续的EOF分析更加准确。

def preprocess_data(data: xr.Dataset) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
    """
    对数据进行预处理,包括计算纬度权重、去除季节循环等。

    参数:
    data (xarray.Dataset): 包含海平面气压数据的数据集对象。

    返回值:
    lon (numpy.ndarray): 经度数据。
    lat (numpy.ndarray): 纬度数据。
    eof (numpy.ndarray): EOF模态。
    pc (numpy.ndarray): PC时间序列。
    var (numpy.ndarray): 解释方差百分比。
    """

    lat = np.array(data.LAT43_65)
    lon = np.array(data.LON41_105)
    pres_data = data.PRES.data

    # 计算纬度权重
    coslat = np.cos(np.deg2rad(lat))
    wgts = np.sqrt(coslat)[..., np.newaxis]

    # 去除季节循环
    nt, nlat, nlon = pres_data.shape
    ngrd = nlon * nlat
    pres_ym = pres_data.reshape((12, round(nt / 12), ngrd), order='F').transpose((102))
    pres_clm = np.mean(pres_ym, axis=0)
    pres_anom = (pres_ym - pres_clm).transpose((102)).reshape((nt, nlat, nlon), order='F')
    # 计算EOF & PC
    solver = Eof(pres_anom, weights=wgts)
    eof = solver.eofsAsCorrelation(neofs=4)
    pc = solver.pcs(npcs=4, pcscaling=1)
    var = solver.varianceFraction(neigs=4)
    return lon, lat, eof, pc, var

solver.eofsAsCorrelation(neofs=4)返回的是主要模态(leading EOF)与输入海表气压(SLP)之间的相关性。

pcscaling=1:表示对主成分时间序列进行缩放,使其具有单位方差。这意味着每个主成分的方差都被归一化为1,因此可以更容易地比较它们的相对重要性,等于0表示不缩放。

solver.eofsAsCorrelation(neofs=4)
solver.eofsAsCorrelation(neofs=4)

修改为solver.eofs(neofs=4)返回的是前4个EOF,即前4个空间模态。这些模态描述了数据集中的主要空间变化模式。

solver.eofs
solver.eofs
  • 定义绘图函数,绘制EOF 和 PC 时间序列

这里绘制 PC 序列时,每12个数值绘制一个点,即每年一个数据


def plot_eof_and_pc(lons, lats, eof, pc, var,  ax1, ax2,EOF,PC):
    """
    绘制 EOF1 和 PC1 时间序列。

    参数:
    lons (numpy.ndarray): 经度数据,表示每个数据点的经度值。
    lats (numpy.ndarray): 纬度数据,表示每个数据点的纬度值。
    eof (numpy.ndarray): 表示 EOF1 的空间模式,表示每个数据点的 EOF1 值。
    pc (numpy.ndarray): 表示 PC1 的时间序列,表示每个时间步的 PC1 值。
    var (float): 表示 EOF1 解释的方差百分比,表示 EOF1 解释的总方差的百分比。
    season (str): 当前季节的字符串表示,用于图表标题。
    ax1 (matplotlib.axes.Axes): 第一个子图的轴对象,带有投影,用于绘制 EOF1 空间模式。
    ax2 (matplotlib.axes.Axes): 第二个子图的轴对象,不带投影,用于绘制 PC1 时间序列。
    """

    clevs = np.linspace(-1141)
    
    fill = ax1.contourf(lons, lats, eof.squeeze(), clevs,
                        transform=ccrs.PlateCarree(), cmap=plt.cm.RdBu_r)
    ax1.add_feature(cfeature.LAND, facecolor='w', edgecolor='k', zorder=1)
    cb = plt.colorbar(fill, ax=ax1,  
                       orientation ='horizontal',
                      shrink=0.75
                     )
    cb.set_label('correlation coefficient', fontsize=12)
    ax1.set_title(f'{EOF}  ', fontsize=16,loc='left')
    gl = ax1.gridlines(draw_labels=True, x_inline=False, y_inline=False, linestyle='dashed')
    gl.top_labels = False
    gl.right_labels = False
    gl.rotate_labels = False
    gl.xlocator = ctk.LongitudeLocator(20)
    gl.ylocator = ctk.LatitudeLocator(8)
    gl.xformatter = ctk.LongitudeFormatter(zero_direction_label=True)
    gl.yformatter = ctk.LatitudeFormatter()

    years = range(int(time_min),int(time_max)+1)
    ax2.plot(years, pc[::12], color='b', linewidth=2)
    ax2.axhline(0, color='k')
    ax2.set_title(f'{PC}  ',loc='left')
    # ax2.set_xlabel('Year')
    ax2.set_ylabel('Normalized Units')
    ax2.set_xlim(int(time_min),int(time_max))
    ax2.set_ylim(-33)
    ax2.set_title(f'Var={var:.2}', loc='right')

  • 主程序:循环绘图

path = r'G:/code_daily/slp.nc'
time_min,time_max = '1980','2012'
data = read_netcdf(path,time_min,time_max)

# 数据预处理
lon, lat, eof, pc,var = preprocess_data(data)

# 绘制 EOF 和 PC
fig = plt.figure(figsize=(1012),dpi=600)

EOFs = ['EOF1''EOF2','EOF3','EOF4',]
PCs = ['PC1''PC2','PC3','PC4']

for i, EOF in enumerate(EOFs):
    
    print(i,EOF,)
    
    # 第一个子图带投影
    ax1 = fig.add_subplot(422*i+1, projection=ccrs.PlateCarree(central_longitude=180))
    # 第二个子图不带投影
    ax2 = fig.add_subplot(422*i+2)
    plot_eof_and_pc(lon, lat, eof[i], pc[:,i], var[i], ax1, ax2,EOFs[i],PCs[i])
plt.tight_layout()
plt.show()

本文由 mdnice 多平台发布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/516162.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Greenplum】GP库 too many clients already错误,重启失败问题解决方案

问题描述&#xff1a; 连接数满了后&#xff0c;导致 gp库无法连接了&#xff0c;通过登录服务器&#xff0c;使用gpadmin用户进行重启操作&#xff0c;也报too many clients already&#xff0c;无法重启。 采用 psql -d postgres -U gpadmin 连接库&#xff0c;也报too man…

C语言----数据在内存中的存储

文章目录 前言1.整数在内存中的存储2.大小端字节序和字节序判断2.1 什么是大小端&#xff1f;2.2 练习 3.浮点数在内存中的存储3.1.引子3.2.浮点数的存储3.2.2 浮点数取的过程 前言 下面给大家介绍一下数据在内存中的存储&#xff0c;这个是一个了解c语言内部的知识点&#xf…

element-ui breadcrumb 组件源码分享

今日简单分享 breadcrumb 组件的源码实现&#xff0c;主要从以下三个方面&#xff1a; 1、breadcrumb 组件页面结构 2、breadcrumb 组件属性 3、breadcrumb 组件 slot 一、breadcrumb 组件页面结构 二、breadcrumb 组件属性 2.1 separator 属性&#xff0c;分隔符&#xff…

Golang | Leetcode Golang题解之第10题正则表达式匹配

题目&#xff1a; 题解&#xff1a; func isMatch(s string, p string) bool {m, n : len(s), len(p)matches : func(i, j int) bool {if i 0 {return false}if p[j-1] . {return true}return s[i-1] p[j-1]}f : make([][]bool, m 1)for i : 0; i < len(f); i {f[i] m…

python--IO流和字符流的写入写出

1.IO流&#xff1a;&#xff08;input output stream&#xff09; python的IO流只有一个函数&#xff1a;open函数 属性不用带括号&#xff1b;方法通通要带括号 输入输出流&#xff1a;狭义上来说&#xff0c;指的就是内存数据和磁盘这种可以永久 存储数据的设备 IO流 IO流…

[C#]OpenCvSharp使用HoughCircles霍夫圆检测算法找出圆位置并计数

【效果展示】 原图&#xff1a; 找出位置&#xff1a; 【测试环境】 vs2019,netframework4.7.2,opencvsharp4.8.0 【函数用法】 cv2提供了一种圆检测的方法&#xff1a;HoughCircles。该函数的返回结果与参数设置有很大的关系。 检测的图像时9枚钱币&#xff0c;分别使用了…

Codeforces Round 931 (Div. 2) ---- E. Weird LCM Operations ---- 题解

E. Weird LCM Operations&#xff1a; 题目大意&#xff1a; 思路解析&#xff1a; 这是一道构造题&#xff0c;那么观察这个构造有啥性质&#xff0c;观察到最多操作次数为 n/6 5&#xff0c;然后每次操作需要选择三个数&#xff0c;如果每次操作的三个数都不和之前的重复的…

算法-最值问题

#include<iostream> using namespace std; int main() {int a[7];//上午上课时间int b[7];//下午上课时间int c[7];//一天总上课时间for (int i 0; i < 7; i) {cin >> a[i] >> b[i];c[i] a[i] b[i];}int max c[0];//max记录最长时间int index -1;//索…

解决 VSCode 编辑器点击【在集成终端中打开】出现新的弹框

1、问题描述 在 VSCode 的项目下&#xff0c;鼠标右键&#xff0c;点击【在集成终端中打开】&#xff0c;出现新的一个弹框。新版的 VSCode 会有这个问题&#xff0c;一般来说我们都希望终端是在 VSCode 的控制台中打开的&#xff0c;那么如何关闭这个弹框呢&#xff1f; 2、解…

震惊!!原来阻塞队列消息队列这样理解会更简单!!!

震惊!!原来阻塞队列&&消息队列这样理解会更简单!!! 一:阻塞队列二:消息队列2.1:生产者消费者模型2.1.1:解耦合:2.1.2:削峰填谷: 三:消息队列代码3.1.13.1.2:3.1.3:生产慢,消费快,消费阻塞3.1.3:生产快,消费慢,生产阻塞 二级目录二级目录 一:阻塞队列 阻塞队列:先进先出…

能耗监测管理系统与技术方案

能耗监测管理系统是目前能源管理中重要的技术手段&#xff0c;它通过集成现代监测技术和信息技术&#xff0c;实现对能源消耗的实时监控、数据分析和决策支持&#xff0c;帮助企业或机构实现能源的高效管理和节能降耗。本篇文章将从能耗监测管理系统的组成、关键技术、应用领域…

数据库重点知识(个人整理笔记)

目录 1. 索引是什么&#xff1f; 1.1. 索引的基本原理 2. 索引有哪些优缺点&#xff1f; 3. MySQL有哪几种索引类型&#xff1f; 4. mysql聚簇和非聚簇索引的区别 5. 非聚簇索引一定会回表查询吗&#xff1f; 6. 讲一讲前缀索引&#xff1f; 7. 为什么索引结构默认使用B…

[技术闲聊]我对电路设计的理解(三)

终于可以独立做项目了&#xff0c;是不是很激动&#xff0c;是不是为自己骄傲和自豪&#xff0c;应该的&#xff0c;奋斗那么久不就是为了站在山巅看看四周的风景嘛&#xff01; 虽说山外还有山&#xff0c;但是此刻就在脚下的山巅上&#xff0c;怡然自得都是不过分的&#xff…

黑马点评part1 -- 短信登录

目录 1 . 导入项目 : 2 . 基于Session实现短信验证登录 2 . 1 原理 : 2 . 2 发送短信验证码 : 2 . 3 短信验证码登录和验证功能 : 2 . 4 登录验证功能 2 . 5 隐藏用户敏感信息 2 . 6 session共享问题 2 . 7 Redis 代替 session 2 . 8 基于Redis实现短信登录 UserS…

FressRTOS_day4:2024/4/4

1.总结二进制信号量和计数型信号量的区别&#xff0c;以及他们的使用场景。 二进制信号量的数值只有0和1。&#xff08;用于共享资源的访问&#xff09;&#xff1b;而计数型信号量的值一般是大于或者等于2&#xff08;用于生产者和消费者模型&#xff09; 2.使用计数型信号量…

JAVAEE——文件IO

文章目录 文件的概念什么是文件&#xff1f;树型结构组织 和 目录文件路径相对路径绝对路径 文件的分类文件的权限 文件读写IO API字符流操作API 警告字节流操作APIInputStreamOutputStream 文件的概念 什么是文件&#xff1f; 我们先来理解一下什么是文件&#xff0c;那么想…

【C++常用函数介绍】isalpha,isalnum、isdigit、islower、isupper 用法

首先 isalpha,isalnum、isdigit、islower、isupper 的使用方法都需要用到一个头文件 #include<ctype.h>其次 系统的介绍以上函数的用法 isalpha()用来判断一个字符是否为字母 isalnum&#xff08;&#xff09;用来判断一个字符是否为数字或者字母&#xff0c;也就是说…

四川尚熠电子商务有限公司靠谱吗?怎么样?

在当下数字化浪潮中&#xff0c;电子商务行业正以前所未有的速度蓬勃发展。四川尚熠电子商务有限公司&#xff0c;作为专注于抖音电商服务的企业&#xff0c;凭借其敏锐的市场洞察力和创新精神&#xff0c;正成为行业内的佼佼者&#xff0c;为众多品牌打开抖音电商市场的大门。…

Stable Diffusion扩散模型【详解】小白也能看懂!!

文章目录 1、Diffusion的整体过程2、加噪过程2.1 加噪的具体细节2.2 加噪过程的公式推导 3、去噪过程3.1 图像概率分布 4、损失函数5、 伪代码过程 此文涉及公式推导&#xff0c;需要参考这篇文章&#xff1a; Stable Diffusion扩散模型推导公式的基础知识 1、Diffusion的整体…

2006-2022年各省研发投入强度数据/研究与试验发展(RD)经费投入强度数据(无缺失)

2006-2022年各省研发投入强度数据/研究与试验发展(R&D)经费投入强度数据(无缺失) 1、时间:2006-2022年 2、范围&#xff1a;31省 3、来源&#xff1a;科技年鉴 4、指标&#xff1a;研发投入强度/研究与试验发展(R&D)经费投入强度 5、指标解释&#xff1a;研发投入…