Scipy FFT频率分析非常嘈杂的信号。

问题描述 投票:8回答:6

我有噪音 资料 我想计算其频率和振幅。每1100秒采集一次样本。从趋势来看,我认为频率是~0.3。

enter image description here

当我使用 numpy fft 模块,最终得到的频率非常高(36.32秒),这显然是不正确的。我试着用 pandas rolling_mean 去除fft前的噪音,但这也没有用。

import pandas as pd
from numpy import fft
import numpy as np
import matplotlib.pyplot as plt

Moisture_mean_x = pd.read_excel("signal.xlsx", header = None)
Moisture_mean_x = pd.rolling_mean(Moisture_mean_x, 10) # doesn't helps
Moisture_mean_x = Moisture_mean_x.dropna()
Moisture_mean_x = Moisture_mean_x -Moisture_mean_x.mean()
frate = 100. #/sec           
Hn = fft.fft(Moisture_mean_x)
freqs = fft.fftfreq(len(Hn), 1/frate)
idx = np.argmax(np.abs(Hn))
freq_in_hertz = freqs[idx]

谁能指导我如何解决这个问题?

python numpy pandas fft
6个回答
5
投票

你是对的,有一些问题。一个需要解释的问pandas的第零列。

Hn = np.fft.fft(Moisture_mean_x[0])

否则就会发生一些错误,你可以从FFT结果不是符号的事实中看出,这应该是真实输入的情况。

result


3
投票

似乎 @tillsten 已经回答了你的问题,但这里有一些补充确认。 第一张图是你的数据(零平均值,我把它改成了csv)。第二张是功率谱密度,你可以看到一个胖乎乎的质量,在大约0.3Hz处有一个峰值。 我把第三张图 "放大",看是否有第二个隐藏频率接近主频。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal

x = pd.read_csv("signal.csv")
x = np.array(x, dtype=float)[:,0]
x = x - np.mean(x)
fs = 1e2

f, Pxx = signal.welch(x, fs, nperseg=1024)
f_res, Pxx_res = signal.welch(x, fs, nperseg=2048)

plt.subplot(3,1,1)
plt.plot(x)

plt.subplot(3,1,2)
plt.plot(f, Pxx)
plt.xlim([0, 1])
plt.xlabel('frequency [Hz]')
plt.ylabel('PSD')

plt.subplot(3,1,3)
plt.plot(f_res, Pxx_res)
plt.xlim([0, 1])
plt.xlabel('frequency [Hz]')
plt.ylabel('PSD')

plt.show()

Hn = fft.fft(x)
freqs = fft.fftfreq(len(Hn), 1/fs)
idx = np.argmax(np.abs(Hn))
freq_in_hertz = freqs[idx]
print 'Main freq:', freq_in_hertz
print 'RMS amp:', np.sqrt(Pxx.max())

这就打印出来了。

Main freq: 0.32012805122
RMS amp: 0.0556044913489

enter image description here


1
投票

FFT是一个滤波器组 只要寻找幅度峰值 只是 在FFT结果中的预期频率范围内(而不是整个结果向量),其他大部分频谱基本上会被过滤掉。


1
投票

没有必要事先对信号进行滤波,因为FFT中的 一个滤波器。只需跳过FFT中与您知道的包含大量噪声的频率相对应的部分--将它们归零,或以其他方式排除它们。


0
投票

我希望这能帮助你。

https:/scipy-cookbook.readthedocs.ioitemsButterworthBandpass.html)。

在应用FFT之前,你应该只过滤预期频率附近的频段,提高信噪比。

编辑。

Mark Ransom给出了一个更聪明的答案,如果你必须做FFT,你可以在变换后直接切断噪声。它不会给出比滤波器更差的结果。


-1
投票

你应该使用低通滤波器,它应该先保留较大的周期性变化,并平滑一些高频率的东西。之后,再可以做FFT来得到峰值。这里有一个 配方 通常用于这类事情。

© www.soinside.com 2019 - 2024. All rights reserved.