Numpyでfft
関数を使用すると、複雑な配列になりました。正確な周波数値を取得する方法は?
_np.fft.fftfreq
_は、係数に関連付けられた周波数を示します。
_import numpy as np
x = np.array([1,2,1,0,1,2,1,0])
w = np.fft.fft(x)
freqs = np.fft.fftfreq(len(x))
for coef,freq in Zip(w,freqs):
if coef:
print('{c:>6} * exp(2 pi i t * {f})'.format(c=coef,f=freq))
# (8+0j) * exp(2 pi i t * 0.0)
# -4j * exp(2 pi i t * 0.25)
# 4j * exp(2 pi i t * -0.25)
_
OPは、周波数をヘルツ単位で見つける方法を尋ねます。式はfrequency (Hz) = abs(fft_freq * frame_rate)
であると思います。
これを示すコードを次に示します。
まず、440 Hzでwaveファイルを作成します。
_import math
import wave
import struct
if __== '__main__':
# http://stackoverflow.com/questions/3637350/how-to-write-stereo-wav-files-in-python
# http://www.sonicspot.com/guide/wavefiles.html
freq = 440.0
data_size = 40000
fname = "test.wav"
frate = 11025.0
amp = 64000.0
nchannels = 1
sampwidth = 2
framerate = int(frate)
nframes = data_size
comptype = "NONE"
compname = "not compressed"
data = [math.sin(2 * math.pi * freq * (x / frate))
for x in range(data_size)]
wav_file = wave.open(fname, 'w')
wav_file.setparams(
(nchannels, sampwidth, framerate, nframes, comptype, compname))
for v in data:
wav_file.writeframes(struct.pack('h', int(v * amp / 2)))
wav_file.close()
_
これにより、ファイル_test.wav
_が作成されます。データを読み込み、FFTし、最大電力の係数を見つけ、対応するfft周波数を見つけてから、ヘルツに変換します。
_import wave
import struct
import numpy as np
if __== '__main__':
data_size = 40000
fname = "test.wav"
frate = 11025.0
wav_file = wave.open(fname, 'r')
data = wav_file.readframes(data_size)
wav_file.close()
data = struct.unpack('{n}h'.format(n=data_size), data)
data = np.array(data)
w = np.fft.fft(data)
freqs = np.fft.fftfreq(len(w))
print(freqs.min(), freqs.max())
# (-0.5, 0.499975)
# Find the peak in the coefficients
idx = np.argmax(np.abs(w))
freq = freqs[idx]
freq_in_hertz = abs(freq * frate)
print(freq_in_hertz)
# 439.8975
_
fft 、高速フーリエ変換により、 fast DFT、離散フーリエの計算を可能にするアルゴリズムの大きなファミリーのメンバーを理解します。等サンプリングされた信号の変換。
[〜#〜] dft [〜#〜] [〜#〜] n [〜#〜] 複素数のリストをリストに変換します [〜#〜] n [〜#〜] 複素数、両方のリストは周期 [〜#〜] n [〜 #〜] 。
ここでは、 fft のnumpy
実装を扱います。
多くの場合、あなたは考える
X = np.fft.fft(x)
)、その要素はサンプリングレート dw 。x
サンプルでdt
でサンプリングされた信号N
の周期(別名期間)は
_T = dt*N
_
X
の基本周波数(Hzおよびrad/s)、DFTは
_df = 1/T
dw = 2*pi/T # =df*2*pi
_
一番上の周波数は ナイキスト周波数
_ny = dw*N/2
_
(それは_dw*N
_ではありません)
特定のインデックス_0<=n<N
_のX = np.fft.fft(x)
の要素に対応する頻度は、次のように計算できます。
_def rad_on_s(n, N, dw):
return dw*n if n<N/2 else dw*(n-N)
_
または単一のスイープで
_w = np.array([dw*nif n<N/2 else dw*(n-N) for n in range(N)])
_
hz単位の周波数を考慮する場合は、_s/w/f/
_
_f = np.array([df*n if n<N/2 else df*(n-N) for n in range(N)])
_
元の信号x
-> y
を、周波数関数のみの形式で周波数領域に演算子を適用して変更したい場合は、w
'砂
_Y = X*f(w)
y = ifft(Y)
_
np.fft.fftfreq
_の紹介もちろんnumpy
には便利な関数_np.fft.fftfreq
_があり、次元のものではなく次元のない周波数を返しますが、簡単
_f = np.fft.fftfreq(N)*N*df
w = np.fft.fftfreq(N)*N*dw
_
頻度は配列の単なるインデックスです。インデックスnでは、頻度は2ですπn /配列の長さ(単位あたりのラジアン)。考慮してください:
>>> numpy.fft.fft([1,2,1,0,1,2,1,0])
array([ 8.+0.j, 0.+0.j, 0.-4.j, 0.+0.j, 0.+0.j, 0.+0.j, 0.+4.j,
0.+0.j])
結果は、インデックス0、2、および6でゼロ以外の値になります。8つの要素があります。これの意味は
2πit/8 × 0 2πit/8 × 2 2πit/8 × 6
8 e - 4i e + 4i e
y ~ ———————————————————————————————————————————————
8