Python 数学建模——傅里叶变换时间序列分析

news2024/11/23 12:09:43

文章目录

    • 前言
    • 原理
    • Python 库函数实现
      • 单周期函数
      • 多周期函数
      • 真实数据挑战

前言

  在数学建模过程中,得到一个序列 x 1 , ⋯   , x n x_1,\cdots,x_n x1,,xn,我们首先要进行数据分析,其中就包括分析数据的周期性。这里的周期性不是数学上严格的周期性,即不必 x i x_i xi 严格等于 x i + T x_{i+T} xi+T,大致相等就可以。
  比如下面是 1700 − 1988 1700-1988 17001988 年间,每一年太阳黑子数量的记录图。太阳黑子数量随着时间是否有一定的周期性?

  光看图片的话,太阳黑子几乎都是在 5 5 5 年内持续增长,随后 5 5 5 年内持续下降,周而复始,大概有一个 10 10 10 年的周期。但是光肉眼看还是太主观了,有没有系统一点的办法?
  傅里叶变换是将时域数据 f ( x ) f(x) f(x) 变换到频域 F ( j ω ) F(\mathrm j\omega) F(jω) 的变换法,根据数据在频域的图象 F ( j ω ) F(\mathrm j\omega) F(jω) 的极大值,我们可以轻松看出 f ( x ) f(x) f(x) 有哪些主要的频率分量。而这些分量就对应 f ( x ) f(x) f(x) 主要的周期。
  本文主要介绍傅里叶变换时间序列分析的 Python 实现,对其原理不过多讲述,可以参考其他文献。

原理

傅里叶变换时间序列分析的用途:可以用来找时间序列的周期,或者主观地观察到了周期后,可以用这个理论验证一下。找到周期后,可以联系问题情境解释原因。如果需要用到 Prophet 的话,还可添加自定义周期性(add_seasonality,详见Python 数学建模——Prophet 时间序列预测_多变量prophet-CSDN博客)。

  傅里叶变换分为连续傅里叶变换(CFT)和离散傅里叶变换(DFT)。由于计算机中只能存储离散信号,计算 CFT 非常不方便,实际都是用的离散傅里叶变换,也称快速傅里叶变换(FFT): y k = ∑ n = 0 N − 1 e − 2 π j k n / N x n {{y}_{k}}=\sum_{n=0}^{N-1}{{{e}^{-2\pi\mathrm jkn/N}}}{{x}_{n}} yk=n=0N1e2πjkn/Nxn  其中 y 1 , ⋯   , y n y_1,\cdots,y_n y1,,yn x 1 , ⋯   , x n x_1,\cdots,x_n x1,,xn 的离散傅里叶变换。

Python 库函数实现

单周期函数

  调用 Python 库函数scipy.fft.fft, scipy.fft.fftfreq可以很好地进行傅里叶变换:

import numpy as np
import matplotlib.pyplot as plt
from scipy.fft import fft, fftfreq
import pandas as pd

N = 400
T = 1.0 / 1000

# 生成一个周期为 1/114 的正弦函数
x = np.linspace(0, N*T, N, endpoint = False)
y = np.sin(114 * 2 * np.pi * x)

# z 是对序列进行离散傅里叶变换的结果,abs 对复数取模
z = np.abs(fft(y))

# fftfreq 根据我们的采样周期和采样点个数,返回对应的频率值序列
# 其返回值按照 0 → 最大正数 → 最小负数 → 0 排列, [:N//2] 取前半部分(正频率)
fx = fftfreq(N, T)[:N//2]

plt.rcParams['font.family'] = 'Euclid'
plt.plot(fx,2.0 / N * z[:N//2])
plt.grid()
plt.show()

  在上面的代码中,我们生成了一个正弦函数 y = sin ⁡ ( 114 × 2 π x ) y=\sin(114\times2\pi x) y=sin(114×2πx),这个函数是一个周期为 T = 1 / 114 T=1/114 T=1/114 的周期函数,因此它具有频率 f = 114 f=114 f=114。代码中, z z z y y y 的离散序列傅里叶变换,最后作图的结果如下所示:

  可以明显地看出,在傅里叶变换之后,频谱图象有一个峰值。理论上,这个峰值对应的频率应该就是 f = 114 f=114 f=114。利用代码print(fx[np.argmax(z)])求出这个极值点是 f 0 = 115 f_0=115 f0=115

关于为什么 f 0 = 115 f_0=115 f0=115 而不是 114 114 114,这是因为程序求出来的 z z z 并不是一个函数,而是函数上的一系列函数值。这些函数值对应的横坐标间隔比较大,影响了 f f f 的精度。

多周期函数

  下面我们尝试 y = sin ⁡ ( 114 × 2 π x ) + sin ⁡ ( 514 × 2 π x ) y=\sin(114\times 2\pi x)+\sin(514\times2\pi x) y=sin(114×2πx)+sin(514×2πx),也就是两个周期函数的叠加,看看能不能同时找出这两个频率分量。

import numpy as np
import matplotlib.pyplot as plt
from scipy.fft import fft, fftfreq
import pandas as pd
from scipy.signal import argrelextrema
N = 500
T = 1.0 / 2500

plt.rcParams['font.family'] = 'Euclid'

# 生成一个周期 1/114 的正弦函数和 1/514 的正弦函数的叠加
x = np.linspace(0, N*T, N, endpoint = False)
y = np.sin(114 * 2 * np.pi * x) + np.sin(514 * 2 * np.pi * x)

# z 是对序列进行离散傅里叶变换的结果,abs 对复数取模
z = np.abs(fft(y))
fx = fftfreq(N, T)
lst = list(zip(fx, 2.0 / N * z))
l = len(fx)
plt.plot(fx[:l//2],2.0 / N * z[:l//2])
plt.plot(fx[l//2:],2.0 / N * z[l//2:])
plt.show()
print(fx[argrelextrema(z,np.greater,order=1)])
# [ 115.  515. -515. -115.]

  作图结果如下所示,通过print(fx[argrelextrema(z,np.greater,order=1)])得出来的极大值点也是 f 1 , 2 , 3 , 4 = 115 , 515 , − 515 , − 115 f_{1,2,3,4}=115,515,-515,-115 f1,2,3,4=115,515,515,115。负频率的出现是因为我们采用傅里叶变换的指数形式,频率值不完全与 114 , 514 114,514 114,514 重合的原因也和上面相同。

真实数据挑战

  上面两个函数都是已知周期,用傅里叶变换去验证,看看 Python 库好不好用,效果真不真。现在给出一个未知周期的函数,让傅里叶变换发挥作用。当然,我们就用之前提到的太阳黑子数据

点击下载路径,Ctrl+S下载太阳黑子数据sunspots.csv表单。

  使用太阳黑子数据sunspots.csv如上图(左)所示。认为它具有一定周期性,编写以下代码分析太阳黑子的周期性,绘制频谱图如上图(右)所示。根据图象可以得出结论,太阳黑子数量在短期内具有大概 10 10 10 天的周期性 f ≈ 0.1 f\approx0.1 f0.1,在长期内具有大概 100 100 100 天的周期性 f ≈ 0.01 f\approx0.01 f0.01

import numpy as np
import matplotlib.pyplot as plt
from scipy.fft import fft, fftfreq
import pandas as pd
from scipy.signal import argrelextrema


df = pd.read_csv("sunspots.csv")
y = df['counts']
y -= y.mean() # 减去均值以消去直流分量

# z 是对序列进行离散傅里叶变换的结果,abs 对复数取模
z = np.abs(fft(y.values))[:N//2]
fx = fftfreq(len(y), 1)[:N//2]
plt.plot(fx,2.0 / N * z)

plt.rcParams['font.family'] = 'Euclid'
plt.show()
# 根据图像找出最尖的那几个峰对应频率
print(fx[argrelextrema(z,lambda x,y: 2.0 / N * x > 13,order=1)])
# [0.01038062 0.08304498 0.0899654  0.10034602]

有关库函数argrelextrema的使用,参见Python 基本库用法:数学建模_数模代码库python-CSDN博客。上面最后一行代码是找出频谱图中纵坐标大于 13 13 13 的点对应的横坐标(频率)。

参考文献:
Fourier Transforms (scipy.fft) — SciPy v1.14.1 Manual
时间序列分析之:傅里叶变换找周期_傅里叶变换去数据周期-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

升级VMware

1、vm17pro安装包 VMware Workstation 17 Pro软件下载: 官网下载:Download VMware Workstation Pro 2、点击下一步更改地址 3、注册码 VMware Workstation 17 Pro注册码: 4A4RR-813DK-M81A9-4U35H-06KND 4、打开虚拟机 注: 升…

Oracle 11gR2打PSU补丁详细教程

1 说明 Oracle的PSU(Patch Set Update)补丁是Oracle公司为了其数据库产品定期发布的更新包,通常每季度发布一次。PSU包含了该季度内收集的一系列安全更新(CPU:Critical Patch Update)以及一些重要的错误修…

集群聊天服务器项目【C++】(四)cmake介绍和简单使用

我们上次用shell命令和vscode编译链接muduo库服务端代码,本章节实现编写CMakeLists.txt来编译项目。本次简单介绍CMake,并用Cmake编译上次的muduo服务器代码。 1.为什么使用cmake 我们在编译项目时,如果编写Makefile的话,常常会…

大数据处理技术:MapReduce综合实训

目录 1 实验名称 2 实验目的 3 实验内容 4 实验原理 5 实验过程或源代码 5.1 WordCount词频统计 5.2 HDFS文件读写 5.3 倒排索引 5.4 网页排序——PageRank算法 6 实验结果 6.1 WordCount词频统计 6.2 HDFS文件读写 6.3 倒排索引 6.4 网页排序——PageRank算法 1…

无人机飞手教员组装、调试高级教学详解

随着无人机技术的飞速发展,其在航拍、农业、救援、监测等多个领域的应用日益广泛,对专业无人机飞手的需求也随之增加。作为无人机飞手教员,掌握无人机的高级组装、调试技能不仅是教学的基础,更是培养学生成为行业精英的关键。本教…

面试官问:你为什么对这个职位感兴趣?

当面试官问到你为什么对某个职位感兴趣时,你的回答应该反映出你对该职位的热情,以及你如何能够为公司带来价值。 重点:在面试前一定要去研究下这家公司,包括他们的团队,文化,产品,服务等各个方…

SOMEIP_ETS_109: SD_Do_not_specify_a_port

测试目的: 验证DUT能够拒绝不包含端口号(端口号为0)的SubscribeEventgroup消息。 描述 本测试用例旨在确保DUT遵循SOME/IP协议,当接收到没有指定端口的SubscribeEventgroup消息时,能够正确地拒绝该订阅尝试。 测试…

单链表各种接口的实现(C)

顺序表的优缺点 顺序表的问题 头部和中部的插入删除效率都不行, O ( N ) O(N) O(N)空间不够了,扩容有一定消耗(尤其是异地扩容)开新空间,拷贝数据,释放旧空间扩容逻辑,可能还存在空间浪费 多扩…

Springboot项目总结

1.为了调用写在其他包里面的类的方法 但是不使用new来实现调用这个类里面的方法,这个时候我们就需要将这个类注入到ioc容器里面,通过ioc容器来实现自动生成一个对象。 对ioc容器的理解:自动将一个对象实现new. 考察了and 和 or组合使用&…

vscode技巧-eslint配置

开发环境 jsvue3axios 下载插件 Eslint、Prettfier 配置过程 1.配置eslint 进入settings,输入eslint,在settings.json中替换一下文件 // #每次保存的时候自动格式化 {"editor.codeActionsOnSave": {"source.fixAll.eslint": &…

海康威视摄像机和录像机的监控与回放

文章目录 海康威视摄像机和录像机的监控与回放1、海康威视监控设备简介1.1、摄像机二次开发1.1.1:协议选择1.1.2:ffmpeg软件转流 2、各种流媒体协议介绍2.1:流媒体协议介绍2.1.1:RTSP (实时流传输协议)2.1.2:RTMP (实时…

Java语言程序设计基础篇_编程练习题**18.26 (创建一个迷宫)

目录 题目:**18.26 (创建一个迷宫) 习题思路 代码示例 输出结果 题目:**18.26 (创建一个迷宫) 编写一个程序,在迷宫中寻找一条路径,如图18-13a所示。该迷宫由一个8 x 8 的棋盘表示。路径必须满足下列条件: 路径在迷…

日志收集工具 Fluentd vs Fluent Bit 的区别

参考链接: FluentdFluentd BitFluentd & Fluent Bit | Fluent Bit: Official Manual Fluentd 与 Fluent Bit 两者都是生产级遥测生态系统! 遥测数据处理可能很复杂,尤其是在大规模处理时。这就是创建 Fluentd 的原因。 Fluentd 不仅仅是…

国产化中间件正在侵蚀开源中间件

开源中间件的发展趋势表明,它们将继续在技术创新和生态建设中发挥重要作用,尤其是在云计算、大数据等新兴技术领域。开源中间件如Apache Kafka、RabbitMQ、ActiveMQ和RocketMQ等在市场上有着广泛的应用。它们在技术社区中得到了良好的支持,并…

k8s中控制器的使用

目录 一、什么是控制器 二、控制器常用类型 三、replicaset控制器 1、replicaset功能 2、replicaset参数说明 3、replicaset示例 四、deployment控制器 1、deployment控制器的功能 2、deployment控制器示例 (1)版本迭代 (2&#x…

MySql的基础讲解

一、初识MySql 数据库:按照数据结构来组织、存储和管理数据的仓库;是一个长期存储在计算机内的、有组织的、可共享 的、统一管理的大量数据的集合; OLTP:联机事务处理,主要是对数据库的增删改查。 OLTP 主要用来记录…

【研赛论文】数学建模2024华为杯论文word/latex模板

国赛结束,研究生瞩目的研赛马上就要来了,相信研究生同学也是在努力的准备当中,在这里祝愿大家能够获得一个好的名次。一举冲出重围,拿下国奖。在数模比赛当中,论文是参赛者唯一能够与评阅老师进行沟通的方式&#xff0…

【Python爬虫系列】_021.异步请求aiohttp

课 程 推 荐我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈虚 拟 环 境 搭 建 :👉👉 Python项目虚拟环境(超详细讲解) 👈👈PyQt5 系 列 教 程:👉👉 Python GUI(PyQt5)文章合集 👈👈

本地部署大模型并使用知识库Windows下Ollama+Docker+MaxKB安装的记录

概要 本文介绍本地部署大模型和知识库的小白方法,可以运行较多种类的大模型,使用的软件为docker和ollama以及MaxKb作为知识库前端。 下载 各安装包可以百度去官网或者github下载或使用,也可以点击下面的的链接和我下载相同的版本。 ollama…

uniapp child.onFieldChange is not a function

uni-forms // 所有子组件参与校验,使用 for 可以使用 awiatfor (let i in childrens) {const child childrens[i];let name realName(child.name);if (typeof child.onFieldChange function) {const result await child.onFieldChange(tempFormData[name]);if (result) {…