1. ホーム
  2. python

[解決済み] Pythonで高速フーリエ変換をプロットする

2022-10-04 06:55:41

質問

私はNumPyとSciPyにアクセスでき、データセットの簡単なFFTを作成したいと思っています。私は2つのリストを持っています、1つは y の値で、もう一つはそれらのタイムスタンプです。 y の値のタイムスタンプです。

これらのリストをSciPyまたはNumPyのメソッドに送り、結果のFFTをプロットする最も簡単な方法は何でしょうか?

私は例を調べましたが、それらはすべて、いくつかの特定のデータポイントの数、および周波数などを持つ偽のデータのセットを作成することに依存しており、単にデータのセットと対応するタイムスタンプでそれを行う方法を本当に示していません。

私は以下の例を試してみました。

from scipy.fftpack import fft

# Number of samplepoints
N = 600

# Sample spacing
T = 1.0 / 800.0
x = np.linspace(0.0, N*T, N)
y = np.sin(50.0 * 2.0*np.pi*x) + 0.5*np.sin(80.0 * 2.0*np.pi*x)
yf = fft(y)
xf = np.linspace(0.0, 1.0/(2.0*T), N/2)
import matplotlib.pyplot as plt
plt.plot(xf, 2.0/N * np.abs(yf[0:N/2]))
plt.grid()
plt.show()

の引数を変更すると fft を私のデータセットに変更してプロットすると、非常に奇妙な結果が得られ、頻度のスケーリングがずれている可能性があるようです。よくわかりません。

以下は、私が FFT しようとしているデータの pastebin です。

http://pastebin.com/0WhjjMkb http://pastebin.com/ksM4FvZS

私が fft() を使用すると、ゼロで大きなスパイクが発生するだけで、他には何も発生しません。

以下は私のコードです。

## Perform FFT with SciPy
signalFFT = fft(yInterp)

## Get power spectral density
signalPSD = np.abs(signalFFT) ** 2

## Get frequencies corresponding to signal PSD
fftFreq = fftfreq(len(signalPSD), spacing)

## Get positive half of frequencies
i = fftfreq>0

##
plt.figurefigsize = (8, 4));
plt.plot(fftFreq[i], 10*np.log10(signalPSD[i]));
#plt.xlim(0, 100);
plt.xlabel('Frequency [Hz]');
plt.ylabel('PSD [dB]')

スペーシングはちょうど xInterp[1]-xInterp[0] .

どのように解決するのですか?

そこで、あなたのコードの機能的に等価な形をIPythonのノートブックで実行してみます。

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import scipy.fftpack

# Number of samplepoints
N = 600
# sample spacing
T = 1.0 / 800.0
x = np.linspace(0.0, N*T, N)
y = np.sin(50.0 * 2.0*np.pi*x) + 0.5*np.sin(80.0 * 2.0*np.pi*x)
yf = scipy.fftpack.fft(y)
xf = np.linspace(0.0, 1.0/(2.0*T), N//2)

fig, ax = plt.subplots()
ax.plot(xf, 2.0/N * np.abs(yf[:N//2]))
plt.show()

非常に合理的と思われる出力が得られます。

工学部で信号処理について考えていたときから、ずいぶん時間が経ちましたが、50と80のスパイクはまさに予想通りです。では、何が問題なのでしょうか?

生データとコメントが投稿されたことを受けて

ここで問題なのは、定期的なデータを持っていないことです。に送り込むデータは常に検査する必要があります。 任意の アルゴリズムに送り込むデータが適切かどうか、常に検査する必要があります。

import pandas
import matplotlib.pyplot as plt
#import seaborn
%matplotlib inline

# the OP's data
x = pandas.read_csv('http://pastebin.com/raw.php?i=ksM4FvZS', skiprows=2, header=None).values
y = pandas.read_csv('http://pastebin.com/raw.php?i=0WhjjMkb', skiprows=2, header=None).values
fig, ax = plt.subplots()
ax.plot(x, y)

<イグ