如何在python中提取与fft值相关的频率
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3694918/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to extract frequency associated with fft values in python
提问by ria
I used fftfunction in numpy which resulted in a complex array. How to get the exact frequency values?
我fft在 numpy 中使用了函数,这导致了一个复杂的数组。如何获得准确的频率值?
采纳答案by unutbu
np.fft.fftfreqtells you the frequencies associated with the coefficients:
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)
The OP asks how to find the frequency in Hertz.
I believe the formula is frequency (Hz) = abs(fft_freq * frame_rate).
OP 询问如何以赫兹为单位找到频率。我相信公式是frequency (Hz) = abs(fft_freq * frame_rate).
Here is some code that demonstrates that.
这里有一些代码可以证明这一点。
First, we make a wave file at 440 Hz:
首先,我们制作一个 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()
This creates the file test.wav.
Now we read in the data, FFT it, find the coefficient with maximum power,
and find the corresponding fft frequency, and then convert to Hertz:
这将创建文件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
回答by kennytm
The frequency is just the index of the array. At index n, the frequency is 2πn/ the array's length (radians per unit). Consider:
频率只是数组的索引。在索引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])
the result has nonzero values at indices 0, 2 and 6. There are 8 elements. This means
结果在索引 0、2 和 6 处具有非零值。有 8 个元素。这意味着
2πit/8 × 0 2πit/8 × 2 2πit/8 × 6
8 e - 4i e + 4i e
y ~ ———————————————————————————————————————————————
8
回答by gboffi
Frequencies associated with DFT values (in python)
与 DFT 值相关的频率(在 python 中)
By fft, Fast Fourier Transform, we understand a member of a large family of algorithms that enable the fastcomputation of the DFT, Discrete Fourier Transform, of an equisampled signal.
通过fft(快速傅里叶变换),我们了解了一大类算法中的一个成员,这些算法能够快速计算等采样信号的 DFT(离散傅里叶变换)。
A DFTconverts a list of Ncomplex numbers to a list of Ncomplex numbers, with the understanding that both lists are periodic with period N.
一个DFT列表转换ň复数到列表ñ复数,但有一项谅解,这两个名单是周期性的,周期ñ。
Here we deal with the numpyimplementation of the fft.
这里我们处理fft的numpy实现。
In many cases, you think of
在很多情况下,你会想到
- a signal xdefined in the time domain of length N, sampled at a constant interval dt,
- its DFT X(here specifically
X = np.fft.fft(x)), whose elements are sampled on the frequency axis with a sample rate dw.
- 在长度为N的时域中定义的信号x,以恒定间隔dt采样,
- 它的 DFT X(这里特别是
X = np.fft.fft(x)),其元素在频率轴上以采样率dw采样。
Some definition
一些定义
the period (aka duration) of the signal
x, sampled atdtwithNsamples is isT = dt*Nthe fundamental frequencies (in Hz and in rad/s) of
X, your DFT aredf = 1/T dw = 2*pi/T # =df*2*pithe top frequency is the Nyquist frequency
ny = dw*N/2(and it's not
dw*N)
用样本
x采样的信号的周期(又名持续时间)是dtNT = dt*N的基本频率(以赫兹和弧度/秒为单位)
X,您的 DFT 是df = 1/T dw = 2*pi/T # =df*2*pi最高频率是奈奎斯特频率
ny = dw*N/2(它不是
dw*N)
The frequencies associated with a particular element in the DFT
与 DFT 中特定元素相关的频率
The frequencies corresponding to the elements in X = np.fft.fft(x)for a given index 0<=n<Ncan be computed as follows:
与给X = np.fft.fft(x)定索引中的元素对应的频率0<=n<N可以计算如下:
def rad_on_s(n, N, dw):
return dw*n if n<N/2 else dw*(n-N)
or in a single sweep
或在一次扫描中
w = np.array([dw*n if n<N/2 else dw*(n-N) for n in range(N)])
if you prefer to consider frequencies in Hz, s/w/f/
如果您更愿意考虑以 Hz 为单位的频率, s/w/f/
f = np.array([df*n if n<N/2 else df*(n-N) for n in range(N)])
Using those frequencies
使用这些频率
If you want to modify the original signal x-> yapplying an operator in the frequency domain in the form of a function of frequency only, the way to go is computing the w's and
如果您想修改原始信号x->y仅以频率函数的形式在频域中应用运算符,则要走的路是计算w的 和
Y = X*f(w)
y = ifft(Y)
Introducing np.fft.fftfreq
介绍 np.fft.fftfreq
Of course numpyhas a convenience function np.fft.fftfreqthat returns dimensionless frequenciesrather than dimensional onesbut it's as easy as
当然numpy有一个方便的函数np.fft.fftfreq,它返回无量纲的频率而不是有维的频率,但它很简单
f = np.fft.fftfreq(N)*N*df
w = np.fft.fftfreq(N)*N*dw
Because df = 1/Tand T = N/sps(spsbeing the number of samples per second) one can also write
因为df = 1/T和T = N/sps(sps每秒样本数)也可以写
f = np.fft.fftfreq(N)*sps

