python - 时间序列的傅里叶变换 (fft),但已清理数据的两端相互靠近
问题描述
我有一个时间序列,它代表虚拟环境中的 X 和 Z 坐标。
X = np.array(df["X"])
Z = np.array(df["Z"])
X 和 Z 坐标都包含来自不同来源的噪声。为了滤除噪音,我想使用傅立叶变换。经过一番研究,我使用了https://medium.com/swlh/5-tips-for-working-with-time-series-in-python-d889109e676d中的代码对我的数据进行去噪。
def fft_denoiser(x, n_components, to_real=True):
n = len(x)
# compute the fft
fft = np.fft.fft(x, n)
# compute power spectrum density
# squared magnitud of each fft coefficient
PSD = fft * np.conj(fft) / n
# keep high frequencies
_mask = PSD > n_components
fft = _mask * fft
# inverse fourier transform
clean_data = np.fft.ifft(fft)
if to_real:
clean_data = clean_data.real
return clean_data
设置 n_components 后,我喜欢使用清理后的数据。正如我为 X 坐标绘制的那样,这非常好:
只有在开始和结束时,清理后的数据突然朝着彼此的值移动......有人可以帮助或解释一下是什么原因造成的,我该如何克服这个问题?
解决方案
您遇到此问题的原因是因为 FFT 隐含地假定提供的输入信号是周期性的。如果您重复原始数据,您会发现在每个周期都存在很大的不连续性(当信号从 ~20 回落到 ~5 时)。一旦去除了一些较高频率的分量,您就会看到边缘处的不那么尖锐的不连续性(开始时有几个样本,结束时有几个样本)。
为了避免这种情况,您可以使用线性 FIR 滤波器在时域中进行滤波,该滤波器可以在没有周期性假设的情况下处理数据序列。
出于这个答案的目的,我构建了一个合成测试信号(您可以使用它来重新创建相同的条件),但您显然可以使用自己的数据来代替:
# Generate synthetic signal for testing purposes
fs = 1 # Hz
f0 = 0.002/fs
f1 = 0.01/fs
dt = 1/fs
t = np.arange(200, 900)*dt
m = (25-5)/(t[-1]-t[0])
phi = 4.2
x = 5 + m*(t-t[0]) + 2*np.sin(2*np.pi*f0*t) + 1*np.sin(2*np.pi*f1*t+phi) + 0.2*np.random.randn(len(t))
现在要设计过滤器,我们可以对_mask
(而不是应用掩码)进行逆变换:
import numpy as np
# Design denoising filter
def freq_sampling_filter(x, n_components):
n = len(x)
# compute the fft
fft = np.fft.fft(x, n)
# compute power spectrum density
# squared magnitud of each fft coefficient
PSD = fft * np.conj(fft) / n
# keep frequencies with large contributions
_mask = PSD > n_components
_coff = np.fft.fftshift(np.real(np.fft.ifft(_mask)))
return _coff
coff = freq_sampling_filter(x, threshold)
然后我们可以简单地应用过滤器scipy.signal.filtfilt
:
from scipy.signal import filtfilt
# apply the denoising filter
cleaned = filtfilt(coff, 1, x, padlen=len(x)-1, padtype='constant')
padtype
to的选择'constant'
确保过滤的值在未过滤数据的开始和结束值处开始和结束。
推荐阅读
- java - 使用 Java8 流过滤列表并获取第一个元素
- css - Vue2:v-move 不适用于“离开”过渡
- typescript - 打字稿。导入“模块/子目录”npm 包时未找到环境声明
- angular - 带有路径的 NativeScript 图像不会加载,但 url 工作正常
- excel - 希望获得有关在 MS-Excel 上使用代码和按钮的帮助和建议
- node.js - Angular 6 错误... calendar.component 没有导出的成员“CalendarComponent”
- c - 函数将多个值返回给主函数
- numpy - 相关 2D 矢量场
- string - 带三引号的字符串在带三引号的字符串内
- mysql - 使用当前日期 mysql 创建 CSV 文件