我正在使用周期图绘制捕获时间序列的季节性,我想使用前十个频率分量来创建季节性时间序列,到目前为止,我绘制了周期图:
data=elec_price[:48*365]
from scipy.signal import periodogram
f, Pxx_den = periodogram(data)
数据是一年的价格子集,间隔30分钟 ,并按振幅对它进行排序后,从Fourier_coefficients列表中捕获了前十个频率分量
fourier_coefficients=Pxx_den.tolist()
fourier_coefficients=pd.DataFrame(fourier_coefficients,columns=['amplitude'])
具有最高振幅的最高频率是: 365,2,730,22,52,5,729,8 ,接下来我需要使用这些最高频率分量来获取时间序列的季节性,我生成了每个频率分量的正弦波,并将它们加在一起绘制时间序列,以为我不确定这是否是正确的方法,因为我记得频率分量应该有一个虚部,但我无法从周期图数据中找到它,其次,我仅假设这些分量中的每一个都是正弦波。
sin_waves=fourier_coefficients.drop(columns=['frequency coneficient','amplitude']).copy()
sin_waves[' sin_wave_1']=0
sin_waves[' sin_wave_2']=0
sin_waves[' sin_wave_3']=0
sin_waves[' sin_wave_4']=0
sin_waves[' sin_wave_5']=0
sin_waves[' sin_wave_6']=0
sin_waves[' sin_wave_7']=0
sin_waves[' sin_wave_8']=0
for i in range(8761):
sin_waves[' sin_wave_1'][i]= fourier_coefficients['amplitude'][365]*math.sin(math.pi*i*365/8761)
sin_waves[' sin_wave_2'][i]= fourier_coefficients['amplitude'][2]*math.sin(math.pi*i*2/8761)
sin_waves[' sin_wave_3'][i]= fourier_coefficients['amplitude'][730]*math.sin(math.pi*i*730/8761)
sin_waves[' sin_wave_4'][i]= fourier_coefficients['amplitude'][22]*math.sin(math.pi*i*22/8761)
sin_waves[' sin_wave_5'][i]= fourier_coefficients['amplitude'][52]*math.sin(math.pi*i*52/8761)
sin_waves[' sin_wave_6'][i]= fourier_coefficients['amplitude'][5]*math.sin(math.pi*i*5/8761)
sin_waves[' sin_wave_7'][i]= fourier_coefficients['amplitude'][729]*math.sin(math.pi*i*729/8761)
sin_waves[' sin_wave_8'][i]= fourier_coefficients['amplitude'][8]*math.sin(math.pi*i*8/8761)
sin_waves['accumulated_sin_wave']=(sin_waves[' sin_wave_1']+sin_waves[' sin_wave_2']
+ sin_waves[' sin_wave_3']+sin_waves[' sin_wave_4']+sin_waves[' sin_wave_5']+
sin_waves[' sin_wave_6']+sin_waves[' sin_wave_7']+sin_waves[' sin_wave_8'])
8761是数据中的样本数。
然后,我绘制了sinaves['accumulated_sin_wave']
以下是第一年的季节性成分图:
答案 0 :(得分:0)
对我来说,更好,更轻松的方法就是使用FFT滤波IFFT模型,它看起来很简单,首先我使用以下方法为数据绘制FFt:
package main
import (
"fmt"
"github.com/bobby96333/goSqlHelper"
)
func main(){
fmt.Println("hello")
conn,err :=goSqlHelper.MysqlOpen("user:password@tcp(127.0.0.1:3306)/dbname")
checkErr(err)
row,err := conn.QueryRow("select * from table where col1 = ? and col2 = ?","123","abc")
checkErr(err)
if *row==nil {
fmt.Println("no found row")
}else{
fmt.Printf("%+v",row)
}
}
func checkErr(err error){
if err!=nil {
panic(err)
}
}
此后,我按幅度对功率列表进行了排序,并使用了前10个频率,这些频率对于我的数据是: 0,365,17155,1,17519,11,17509,366,17154,2,17518 请注意,0是数据中的DC分量,因此您可以使用或不使用它,具体取决于您是否要抵消季节性变化。 另外,请注意,这些频率中的每一个都是偶数,每个偶数都是彼此的镜像,因为FFT是一个绘图,其中每个频率分量及其负频率具有相同的功率。 选择了我的前5个频率后,我过滤了FFT_filtered列表:
one_year_values=48*365
data=elec_price[:one_year_values]
from numpy.fft import fft, fftfreq, ifft
n=len(data)
freqs=fftfreq(n)
mask = freqs>0
fft_values=fft(data)
fft_list=np.copy(fft_values).tolist()
fft_filtered=np.copy(fft_list).tolist() # copying from the original fft list in order to filter it
power= 2*(np.abs(fft_values/one_year_values))**2 # calculating the power make sit easy to compare between frequency components, because they are complex numbers, and the power of them gets the absolute values of them.
power=power.tolist()
然后,我使用IFFT验证FFt,以使用前5个频率获得数据图:
tuple(fft_filtered)
for i in range(len(fft_filtered)):
fft_filtered[i]=0
for i in (0
,365
,17155
,1
,17519
,11
,17509
,366
,17154
,2
,17518):
fft_filtered[i]=fft_list[i]
,这是反向列表的图解: 1 year seasonality using top 5 frequencies