如何在python中对段实现/执行DFT?

如何在python中对段实现/执行DFT?,python,plot,window,fft,dft,Python,Plot,Window,Fft,Dft,我正在尝试用python编写一个简单的程序,它将计算并显示1段的DFT输出 我的信号是3秒长,我想计算每10毫秒长段的DFT。抽样率为44100。所以一个片段有441个样本长 由于我正处于测试阶段,而原始程序要大得多(语音识别),所以这里有一个单独的部分用于测试,不幸的是,它的行为很奇怪。或者是因为我对这个问题缺乏知识 我在某个地方读到DFT输入应该四舍五入到2的幂,所以我将数组排列为512而不是441。这是真的吗 如果我以44100的频率采样,最多可以达到22050Hz的频率,对于长度为512

我正在尝试用python编写一个简单的程序,它将计算并显示1段的DFT输出

我的信号是3秒长,我想计算每10毫秒长段的DFT。抽样率为44100。所以一个片段有441个样本长

由于我正处于测试阶段,而原始程序要大得多(语音识别),所以这里有一个单独的部分用于测试,不幸的是,它的行为很奇怪。或者是因为我对这个问题缺乏知识

  • 我在某个地方读到DFT输入应该四舍五入到2的幂,所以我将数组排列为512而不是441。这是真的吗

  • 如果我以44100的频率采样,最多可以达到22050Hz的频率,对于长度为512(~441)的样本,至少可以达到100Hz

  • 如果2。如果是真的,那么我可以在10毫秒的段中拥有100赫兹和220赫兹之间的所有频率,但段的长度仅为512(441)个样本,fft的输出返回256(220)个值的数组,它们不能包含所有21950个频率,对吗

  • 我的第一个猜测是
    fft
    的输出值应该乘以100,因为10ms是一秒的100。这是个好理由吗

  • 以下两个给定频率1000和2000的程序在图形上返回两个峰值,分别位于输出阵列中的位置24和48以及图形上的位置2071和位置4156。由于数字的比率是可以的(2000:1000=48:24),我想知道是否应该忽略
    fft
    输出的一些起始部分

    import matplotlib.pyplot as plt
    import numpy as np
    
    t = np.arange(0, 1, 1/512.0)  # We create 512 long array
    
    # We calculate here two sinusoids together at 1000hz and 2000hz
    y = np.sin(2*np.pi*1000*t) + np.sin(2*np.pi*2000*t)
    n = len(y)
    k = np.arange(n)
    
    # Problematic part is around here, I am not quite sure what
    # should be on the horizontal line
    T = n/44100.0
    frq = k/T
    frq = frq[range(n/2)]
    
    
    Y = fft(y)  
    Y = Y[range(n/2)]
    # Convert from complex numbers to magnitudes
    iY = []
    for f in Y:
        iY.append(np.sqrt(f.imag * f.imag + f.real * f.real))
    
    
    plt.plot(frq, iY,  'r')
    plt.xlabel('freq (HZ)')
    plt.show()
    
    1) 我在某处读到DFT输入应该四舍五入到2的幂 我将数组排列为512而不是441。这是真的吗

    是的,DFT长度应该是2的幂。只需将输入填充为零即可匹配512

    2) 如果我以44100的速率采样,最多可以达到频率 22050hz,长度512(~441)的样品至少100hz

    是的,你能得到的最高频率是采样率的一半,它被称为奈奎斯特频率

    不,您得到的最低频率单元(DFT的第一个单元)称为直流分量,并标记信号的平均值。在您的情况下,下一个最低频率单元是22050/256=86Hz,然后是172Hz、258Hz,依此类推,直到22050Hz。 您可以使用
    numpy.fftfreq()
    函数获取此频率

    3) 如果2)是真的,那么我可以让所有频率在100hz和100hz之间 在10ms段中为22050hz,但段的长度为512(441) 仅采样,fft的输出返回256(220)个值的数组,它们 不能包含所有21950个频率,对吗

    DFT不会丢失原始信号的数据,但当DFT大小较小时,它缺乏准确性。您可以对其进行零填充以使DFT大小更大,例如1024或2048

    DFT bin是指以N个输出中的每一个为中心的频率范围 要点。料仓的宽度为采样率/2, 它从:中心频率-(采样率/N)/2扩展到中心频率 频率+(采样率/N)/2。换言之,垃圾箱的一半延伸 在N个输出点中的每一点下方,在其上方各半个

    4) 我的第一个猜测是fft输出中的值应该是 乘以100,因为10毫秒是一秒的100分之一。这个好吗 推理

    否,如果要保留幅值,则不应乘以该值

    以下两个给定频率1000和2000的程序返回 图形上输出阵列中位置24和48处的两个尖峰和 图上的~2071和~4156。因为数字的比例是可以的 (2000:1000=48:24)我想知道我是否应该忽略这本书的开头部分 fft输出

    DFT结果反映在实际输入中。换句话说,你的频率如下:

    n  0   1   2   3    4   ... 255   256   257   ... 511 512
    Hz DC  86  172 258  344 ... 21964 22050 21964 ... 86  0
    
  • 我在某处读到DFT输入应该四舍五入到2的幂,所以我将数组排列为512而不是441。这是真的吗
  • DFT适用于所有尺寸。然而,对于可以在小素数中分解的大小,DFT(如FFT)的实现通常更有效。有些库实现有限制,不支持除2次幂以外的大小,但
    numpy
    的情况并非如此

  • 如果我以44100的频率采样,最多可以达到22050Hz的频率,对于长度为512(~441)的样本,至少可以达到100Hz
  • 正如您正确指出的,均匀尺寸DFT的最高频率为44100/2=22050Hz。请注意,对于奇数大小的DFT,最高频率单元将对应于略小于奈奎斯特频率的频率。至于最小频率,它将始终为0Hz。下一个非零频率将是
    44100.0/N
    ,其中
    N
    是样本中的DFT长度(如果使用441个样本的DFT长度,~86Hz的DFT长度为512个样本,则给出100Hz)

  • 如果2)是真的,那么我可以在10ms的段中有100Hz和22050Hz之间的所有频率,但段的长度仅为512(441)个样本,fft的输出返回256(220)个值的数组,它们不能包含所有21950个频率,对吗
  • 首先,100Hz和22050Hz之间没有21950个频率,因为频率是连续的,不限于整数频率。这就是说,您正确地认识到DFT的输出将被限制在更小的频率集。更具体地说,DFT表示离散频率阶跃下的频谱:0,
    44100/N
    2*44100/N

  • 我的第一个猜测是FFT的输出值应该乘以100,因为10ms是一秒的100。这是个好理由吗
  • 不需要将FFT输出乘以100。但是如果你的意思是100Hz的倍数,DFT长度为441,采样率为44100Hz,那么你的猜测是正确的

    以下程序适用于两个给定频率1000
    t = np.arange(0, 1, 1/512.0)  # We create 512 long array
    
    t = np.arange(0, 511.0/44100, 1/44100.0)