我有嘈杂的data我想要计算频率和幅度。每1/100秒收集样品。从趋势来看,我认为频率为~0.3
当我使用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]
有人可以指导我如何解决这个问题吗?
答案 0 :(得分:3)
似乎 @tillsten 已经回答了你的问题,但这里有一些额外的确认。第一个图是您的数据(零均值,我将其更改为csv)。第二个是功率谱密度,你可以看到一个峰值在~0.3 Hz的脂肪质量。我缩放了#39;在第三个图上看是否有第二个隐藏频率接近主频率。
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
答案 1 :(得分:0)
我希望这对你有所帮助。
http://wiki.scipy.org/Cookbook/ButterworthBandpass
在应用FFT之前,您应该仅过滤预期频率附近的频段并提高信号噪声比。
编辑:
Mark Ransom给出了一个更明智的答案,如果你必须进行FFT,你可以在转换后切断噪音。它不会产生比过滤器更差的结果。
答案 2 :(得分:-1)
你应该使用一个低通滤波器,它应该保持较大的周期性变化并首先消除一些较高频率的东西。之后,然后可以进行FFT以获得峰值。这是一个recipe for FIR filter,通常用于这种确切的事情。