从时间序列数据确定傅立叶系数

如何解决从时间序列数据确定傅立叶系数

我问了一个自删除后的问题,关于如何从时间序列数据中确定傅立叶系数。我之所以重新提交,是因为我更好地解决了这个问题,并提出了解决方案,因为我认为其他人可能会发现这非常有用。

我有一些时间序列数据,这些数据已分为等距的时间仓(这对我的解决方案至关重要),然后我要根据该数据确定最佳的傅立叶级数(或任何函数)描述数据。这是MWE,其中包含一些测试数据,以显示我要拟合的数据:

import numpy as np
import matplotlib.pyplot as plt

# Create a dependent test variable to define the x-axis of the test data.
test_array = np.linspace(0,1,101) - 0.5

# Define some test data to try to apply a Fourier series to.
test_data = [0.9783883464566918,0.979599093567252,0.9821424606299206,0.9857575507812502,0.9899278899999995,0.9941848228346452,0.9978438300395263,1.0003009205426352,1.0012208923679058,1.0017130521235522,1.0021799664031628,1.0027475606936413,1.0034168260869563,1.0040914266144825,1.0047781181102355,1.005520348837209,1.0061899214145387,1.006846206627681,1.0074483048543692,1.0078691461988312,1.008318736328125,1.008446947572815,1.00862051262136,1.0085134881422921,1.008337095516569,1.0079539881889774,1.0074857334630352,1.006747783037474,1.005962048923679,1.0049115434782612,1.003812267822736,1.0026427549407106,1.001251963531669,0.999898555335968,0.9984976286266923,0.996995982142858,0.9955652088974847,0.9941647321428578,0.9927727076023389,0.9914750532544377,0.990212467710371,0.9891098035363466,0.9875998927875242,0.9828093773946361,0.9722532524271845,0.9574084365384614,0.9411012303149601,0.9251820309477757,0.9121488392156851,0.9033119748549322,0.9002445803921568,0.9032760564202343,0.91192435882353,0.9249696964980555,0.94071381372549,0.957139088974855,0.9721083392156871,0.982955287937743,0.9880613320235758,0.9897455322896282,0.9909590626223097,0.9922601592233015,0.9936513112840472,0.9951442427184468,0.9967071285988475,0.9982921493123781,0.9998775465116277,1.001389230174081,1.0029109110251453,1.0044033691406251,1.0057110841487276,1.0069551867704276,1.008118776264591,1.0089884470588228,1.0098663972602735,1.0104514566473979,1.0109849223300964,1.0112043902912626,1.0114717968750002,1.0113343036750482,1.0112205972495087,1.0108811786407768,1.010500276264591,1.0099054552529192,1.009353759223301,1.008592596116505,1.007887223091976,1.0070715634615386,1.0063525891472884,1.0055587861271678,1.0048733732809436,1.0041832862669238,1.0035913326848247,1.0025318871595328,1.000088536345776,0.9963596140350871,0.9918380684931506,0.9873937281553398,0.9833394624277463,0.9803621496062999,0.9786476100386117]

# Create a figure to view the data.
fig,ax = plt.subplots(1,figsize=(6,6))

# Plot the data.
ax.scatter(test_array,test_data,color="k",s=1)

这将输出以下内容:

Output of problem description

问题是如何确定最能描述此数据的傅立叶级数。确定傅立叶系数的常用公式是在整数中插入一个函数,但是如果我有描述数据的函数,则根本不需要傅立叶系数。查找该系列的全部目的是要具有数据的功能表示。如果没有这样的函数,那么如何找到系数呢?

解决方法

我对这个问题的解决方案是使用NumPy的快速傅立叶变换numpy.fft.fft()实现离散傅立叶变换到数据。这就是为什么按FFT要求在时间上均匀间隔数据至关重要。尽管通常将FFT用于频谱分析,但所需的傅立叶系数与该函数的输出直接相关。

具体地说,此函数输出一系列复数值系数 c 。这些系数的实部为n a / 2,虚部为n b / 2,其中n是拟合的数据点数(上例中为101) )和 a b 正是标准的Fourier级数系数。零阶 a 系数是个例外,因为因子2下降了。因此,FFT允许直接计算傅立叶系数。这是我针对此问题的解决方案的MWE,扩展了上面给出的示例:

import numpy as np
import matplotlib.pyplot as plt

# Set the number of equal-time bins to create.
n_bins = 101

# Set the number of Fourier coefficients to use.
n_coeff = 51

# Define a function to generate a Fourier series based on the coefficients determined by the Fast Fourier Transform.
# This also includes a series of phases x to pass through the function.
def create_fourier_series(x,coefficients):

    # Begin the series with the zeroeth-order Fourier coefficient.
    fourier_series = coefficients[0][0]

    # Now generate the first through n_coeff'th terms.  The period is defined to be 1 since we're operating in phase
    # space.
    for n in range(1,n_coeff):
        fourier_series += (fourier_coeff[n][0] * np.cos(2 * np.pi * n * x) + fourier_coeff[n][1] * 
                           np.sin(2 * np.pi * n * x))

    return fourier_series

# Create a dependent test variable to define the x-axis of the test data.
test_array = np.linspace(0,1,101) - 0.5

# Define some test data to try to apply a Fourier series to.
test_data = [0.9783883464566918,0.979599093567252,0.9821424606299206,0.9857575507812502,0.9899278899999995,0.9941848228346452,0.9978438300395263,1.0003009205426352,1.0012208923679058,1.0017130521235522,1.0021799664031628,1.0027475606936413,1.0034168260869563,1.0040914266144825,1.0047781181102355,1.005520348837209,1.0061899214145387,1.006846206627681,1.0074483048543692,1.0078691461988312,1.008318736328125,1.008446947572815,1.00862051262136,1.0085134881422921,1.008337095516569,1.0079539881889774,1.0074857334630352,1.006747783037474,1.005962048923679,1.0049115434782612,1.003812267822736,1.0026427549407106,1.001251963531669,0.999898555335968,0.9984976286266923,0.996995982142858,0.9955652088974847,0.9941647321428578,0.9927727076023389,0.9914750532544377,0.990212467710371,0.9891098035363466,0.9875998927875242,0.9828093773946361,0.9722532524271845,0.9574084365384614,0.9411012303149601,0.9251820309477757,0.9121488392156851,0.9033119748549322,0.9002445803921568,0.9032760564202343,0.91192435882353,0.9249696964980555,0.94071381372549,0.957139088974855,0.9721083392156871,0.982955287937743,0.9880613320235758,0.9897455322896282,0.9909590626223097,0.9922601592233015,0.9936513112840472,0.9951442427184468,0.9967071285988475,0.9982921493123781,0.9998775465116277,1.001389230174081,1.0029109110251453,1.0044033691406251,1.0057110841487276,1.0069551867704276,1.008118776264591,1.0089884470588228,1.0098663972602735,1.0104514566473979,1.0109849223300964,1.0112043902912626,1.0114717968750002,1.0113343036750482,1.0112205972495087,1.0108811786407768,1.010500276264591,1.0099054552529192,1.009353759223301,1.008592596116505,1.007887223091976,1.0070715634615386,1.0063525891472884,1.0055587861271678,1.0048733732809436,1.0041832862669238,1.0035913326848247,1.0025318871595328,1.000088536345776,0.9963596140350871,0.9918380684931506,0.9873937281553398,0.9833394624277463,0.9803621496062999,0.9786476100386117]

# Determine the fast Fourier transform for this test data.
fast_fourier_transform = np.fft.fft(test_data)

# Create an empty list to hold the values of the Fourier coefficients.
fourier_coeff = []

# Loop through the FFT and pick out the a and b coefficients,which are the real and imaginary parts of the
# coefficients calculated by the FFT.
for n in range(0,n_coeff):
    if n == 0:
        a = fast_fourier_transform[n].real / n_bins
        b = -fast_fourier_transform[n].imag / n_bins # This is always 0.
    else:
        a = 2 * fast_fourier_transform[n].real / n_bins
        b = -2 * fast_fourier_transform[n].imag / n_bins
    fourier_coeff.append([a,b])

# Create the Fourier series approximating this data.
fourier_series = create_fourier_series(test_array - 0.505,fourier_coeff)

# Create a figure to view the data.
fig,ax = plt.subplots(1,figsize=(6,6))

# Plot the data.
ax.scatter(test_array,test_data,color="k",s=1)

# Plot the Fourier series approximation.
ax.plot(test_array,fourier_series,color="b",lw=0.5)

这将输出以下内容:

Output of problem solution

请注意,当我定义傅立叶级数曲线时(等于-0.505),存在的常数因子是该数据生成方式的结果。具体来说,数据的范围是-0.5到0.5,但FFT假定它的范围是0.0到1.0,因此必须将-0.5移位。添加了额外的-0.005以更正未知来源的偏移量。

我发现这对于不包含非常尖锐和狭窄的不连续性的数据非常有效。我很想知道是否有人对这个问题有其他建议的解决方法,希望人们能清楚并有帮助的解释。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)> insert overwrite table dwd_trade_cart_add_inc > select data.id, > data.user_id, > data.course_id, > date_format(
错误1 hive (edu)> insert into huanhuan values(1,'haoge'); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive> show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 <configuration> <property> <name>yarn.nodemanager.res