[英]how to extract frequency associated with fft values in python
我在 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 的波形文件:
import math
import wave
import struct
if __name__ == '__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 __name__ == '__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 (快速傅立葉變換),我們了解了一大類算法中的一個成員,這些算法能夠快速計算等采樣信號的 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*n if 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
因為df = 1/T
和T = N/sps
( sps
是每秒的樣本數)也可以寫
f = np.fft.fftfreq(N)*sps
頻率只是數組的索引。 / the array's length (radians per unit).在索引n 處,頻率為 2 / 陣列的長度(每單位弧度)。 考慮:
>>> 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.