如何去除时间序列中的特定谐波?

How to remove particular harmonics in time series?

我有一个时间序列,其中包含 2014 年到 2019 年的每小时(移动平均)数据。

我使用 fft() 函数查找谐波,并使用 quantmod::findPeaks() 查找最高值的位置,结果得到以下位置:8 56 2193 4384 6575 8766 306737 308928 311119 313310 315447 315495 (时间序列中有 315499 个元素)。

现在我需要将其转换回时域,但用零代替这些位置的数据值。我该怎么做?

此外,我注意到当我绘制fft()函数(FFT的绝对值)时,x轴仍然显示2014年到2019年。它不应该变成Hz轴吗(频率)?

z 是我的时间序列

FFT <- fft(z)
FFT <- abs(FFT/FFT[1])
plot(FFT)

PK <- findPeaks(FFT, thresh = T)
PK

PK的结果就是我提到的12个峰值,代表最高的谐波失真。 我需要删除那些。我相信我可以简单地对 12 个峰进行 FFT[8]=0,但我不确定。 (我试过了,但它不会让我倒转回时域)

我还需要证明生成的 FFT 图确实是傅立叶频谱,但 x 轴不是频率。知道如何进行修正吗?

模拟方波 +(低)噪声

set.seed(101)
ncycles <- 20
len <- 50
z <- rep(rep(0:1,each=len),ncycles) + rnorm(len*ncycles,mean=0, sd=0.02)
plot(z,type="l")

FFT 并找到峰值

f <- fft(z)
F <- abs(f/f[1])
PK <- quantmod::findPeaks(F,thresh=0.01)

绘制 sqrt(功率谱):

plot(F,type="l")
abline(v=PK,col=2)

峰归零:

fz <- f
## position of 'peaks' is actually *one before* PK (not sure why?)
fz[PK-1] <- 0

逆变换,与原版对比:

zz <- Re(fft(fz,inverse=TRUE))/length(f)
plot(z,type="l")
lines(zz,type="l",col=2)