亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

從時間序列數據確定傅立葉系數

從時間序列數據確定傅立葉系數

Helenr 2023-09-26 17:19:25
我問了一個關于如何從時間序列數據確定傅立葉系數的已刪除問題。我重新提交這個問題是因為我已經更好地闡述了這個問題,并且有一個解決方案,我將給出這個解決方案,因為我認為其他人可能會發現這非常有用。我有一些時間序列數據,我已將它們分箱到等間隔的時間箱中(這一事實對我的解決方案至關重要),并且從這些數據中我想確定最能描述數據的傅里葉級數(或任何函數,實際上) 。這是一個帶有一些測試數據的 MWE,用于顯示我想要擬合的數據:import numpy as npimport 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,]# Create a figure to view the data.fig, ax = plt.subplots(1, 1, figsize=(6, 6))# Plot the data.ax.scatter(test_array, test_data, color="k", s=1)輸出如下:問題是如何確定最能描述該數據的傅里葉級數。確定傅里葉系數的常用公式需要在積分中插入一個函數,但如果我有一個函數來描述數據,我根本不需要傅里葉系數;找到這個系列的全部目的是獲得數據的函數表示。如果沒有這樣的函數,那么,系數是如何找到的呢?
查看完整描述

2 回答

?
慕桂英4014372

TA貢獻1871條經驗 獲得超13個贊

我對這個問題的解決方案是使用 NumPy 的快速傅里葉變換實現 numpy.fft.fft() 對數據應用離散傅里葉變換;這就是為什么數據在時間上均勻分布至關重要,因為 FFT 需要這樣做。雖然 FFT 通常用于執行頻譜分析,但所需的傅立葉系數與該函數的輸出直接相關。

具體來說,該函數輸出一系列i個復值系數c。傅立葉級數系數可使用以下關系式求得:

https://img1.sycdn.imooc.com//6512a27d0001123c01150084.jpg

因此,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] / 2


    # 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, n_bins) - 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[n_bins / 2:] + test_data[:n_bins / 2])


# 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):

    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, fourier_coeff)


# Create a figure to view the data.

fig, ax = plt.subplots(1, 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)

輸出如下:

https://img1.sycdn.imooc.com//6512a29300012e0b03170297.jpg

請注意,我如何定義 FFT(導入數據的后半部分,然后導入前半部分)是該數據生成方式的結果。具體來說,數據從 -0.5 到 0.5 運行,但 FFT 假設它從 0.0 運行到 1.0,因此需要進行此轉換。

我發現這對于不包含非常尖銳和狹窄不連續性的數據非常有效。我很想聽聽是否有人對這個問題有其他建議的解決方案,我希望人們發現這個解釋清晰且有幫助。


查看完整回答
反對 回復 2023-09-26
?
慕勒3428872

TA貢獻1848條經驗 獲得超6個贊

不確定它是否對您有幫助;我寫了一個程序來插入你的數據。這是使用 Buildingblocks==0.0.15 完成的


請看下面,


import matplotlib.pyplot as plt

from buildingblocks import bb

import numpy as np


Ydata = [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]



Xdata=list(range(0,len(Ydata)))

Xnew=list(np.linspace(0,len(Ydata),200))

Ynew=bb.interpolate(Xdata,Ydata,Xnew,40)


plt.figure()

plt.plot(Xdata,Ydata)

plt.plot(Xnew,Ynew,'*')

plt.legend(['Given Data', 'Interpolated Data'])


plt.show()

如果你想進一步編寫代碼,我也給出了代碼,以便你可以查看源代碼并學習:


import module

import inspect

src = inspect.getsource(module)

print(src)


查看完整回答
反對 回復 2023-09-26
  • 2 回答
  • 0 關注
  • 196 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號