从 fft 图表中消除噪音
Erasing noise from fft chart
你知道如何从 FFT 中删除这么多噪声吗?
这是我的 FFT 代码:
import numpy as np
fft1 = (Bx[51:-14])
fft2 = (By[1:-14])
# Loop for FFT data
for dataset in [fft1]:
dataset = np.asarray(dataset)
psd = np.abs(np.fft.fft(dataset))**2
freq = np.fft.fftfreq(dataset.size, float(300)/dataset.size)
plt.semilogy(freq[freq>0], psd[freq>0]/dataset.size**2, color='r')
for dataset2 in [fft2]:
dataset2 = np.asarray(dataset2)
psd2 = np.abs(np.fft.fft(dataset2))**2
freq2 = np.fft.fftfreq(dataset2.size, float(300)/dataset2.size)
plt.semilogy(freq2[freq2>0], psd2[freq2>0]/dataset2.size**2, color='b')
我得到的:
我需要的:
有什么想法吗? Welch 不起作用,所以如您所见,我不想平滑我的图表,而是将这么多噪音消除到第二张图片上显示的水平。
韦尔奇是这样做的:
和一些代码:
freqs, psd = scipy.signal.welch(dataset, fs=300, window='hamming')
更新韦尔奇:
一段代码:
# Loop for FFT data
for dataset in [fft1]:
dataset = np.asarray(dataset)
freqs, psd = welch(dataset, fs=266336/300, window='hamming', nperseg=512)
plt.semilogy(freqs, psd/dataset.size**2, color='r')
for dataset2 in [fft2]:
dataset2 = np.asarray(dataset2)
freqs2, psd2 = welch(dataset2, fs=266336/300, window='hamming', nperseg=512)
plt.semilogy(freqs2, psd2/dataset2.size**2, color='b')
如您所见,Welch 配置良好,它显示 60 Hz 电力线和谐波模式。这几乎是好的,但它完全平滑了我的情节。请参见所需的图二。顺便提一句。 Welch plot 的 y 刻度是错误的,但这只是两者的功率数据的一个例子。
我已更改为 nperseg=8192 并且有效。看看结果。
这是一个示例,说明如何使用 nperseg
来控制频率分辨率与降噪之间的权衡:
将 nperseg
设置为信号的长度或多或少等同于使用没有任何平均的 FFT。
下面是生成这张图片的代码:
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt
plt.figure(figsize=[8, 12])
n = 2**21
fs = 887
# example data
x = np.random.randn(n)
x += np.sin(np.cumsum(0.42 + np.random.randn(n) * 0.01)) * 5
x = signal.lfilter([1, 0.5], 2, x)
plt.subplot(3, 2, 1)
plt.semilogy(np.abs(np.fft.fft(x)[:n//2])**2 / n**2, label='FFT')
plt.legend(loc='best')
for i, nperseg in enumerate([128, 512, 8192, 65536, n]):
plt.subplot(3, 2, i+2)
f, psd = signal.welch(x, fs=fs, window='hamming', nperseg=nperseg, noverlap=0)
plt.semilogy(f, psd, label='nperseg={}'.format(nperseg))
plt.legend(loc='best')
plt.show()
你知道如何从 FFT 中删除这么多噪声吗? 这是我的 FFT 代码:
import numpy as np
fft1 = (Bx[51:-14])
fft2 = (By[1:-14])
# Loop for FFT data
for dataset in [fft1]:
dataset = np.asarray(dataset)
psd = np.abs(np.fft.fft(dataset))**2
freq = np.fft.fftfreq(dataset.size, float(300)/dataset.size)
plt.semilogy(freq[freq>0], psd[freq>0]/dataset.size**2, color='r')
for dataset2 in [fft2]:
dataset2 = np.asarray(dataset2)
psd2 = np.abs(np.fft.fft(dataset2))**2
freq2 = np.fft.fftfreq(dataset2.size, float(300)/dataset2.size)
plt.semilogy(freq2[freq2>0], psd2[freq2>0]/dataset2.size**2, color='b')
我得到的:
我需要的:
有什么想法吗? Welch 不起作用,所以如您所见,我不想平滑我的图表,而是将这么多噪音消除到第二张图片上显示的水平。
韦尔奇是这样做的:
freqs, psd = scipy.signal.welch(dataset, fs=300, window='hamming')
更新韦尔奇:
一段代码:
# Loop for FFT data
for dataset in [fft1]:
dataset = np.asarray(dataset)
freqs, psd = welch(dataset, fs=266336/300, window='hamming', nperseg=512)
plt.semilogy(freqs, psd/dataset.size**2, color='r')
for dataset2 in [fft2]:
dataset2 = np.asarray(dataset2)
freqs2, psd2 = welch(dataset2, fs=266336/300, window='hamming', nperseg=512)
plt.semilogy(freqs2, psd2/dataset2.size**2, color='b')
如您所见,Welch 配置良好,它显示 60 Hz 电力线和谐波模式。这几乎是好的,但它完全平滑了我的情节。请参见所需的图二。顺便提一句。 Welch plot 的 y 刻度是错误的,但这只是两者的功率数据的一个例子。
我已更改为 nperseg=8192 并且有效。看看结果。
这是一个示例,说明如何使用 nperseg
来控制频率分辨率与降噪之间的权衡:
将 nperseg
设置为信号的长度或多或少等同于使用没有任何平均的 FFT。
下面是生成这张图片的代码:
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt
plt.figure(figsize=[8, 12])
n = 2**21
fs = 887
# example data
x = np.random.randn(n)
x += np.sin(np.cumsum(0.42 + np.random.randn(n) * 0.01)) * 5
x = signal.lfilter([1, 0.5], 2, x)
plt.subplot(3, 2, 1)
plt.semilogy(np.abs(np.fft.fft(x)[:n//2])**2 / n**2, label='FFT')
plt.legend(loc='best')
for i, nperseg in enumerate([128, 512, 8192, 65536, n]):
plt.subplot(3, 2, i+2)
f, psd = signal.welch(x, fs=fs, window='hamming', nperseg=nperseg, noverlap=0)
plt.semilogy(f, psd, label='nperseg={}'.format(nperseg))
plt.legend(loc='best')
plt.show()