tft每日頭條

 > 生活

 > python學習算法

python學習算法

生活 更新时间:2024-06-30 17:16:47

python學習算法?SciPy提供了FFTpack模塊,包含了傅裡葉變換的算法實現,我來為大家科普一下關于python學習算法?下面希望有你要的答案,我們一起來看看吧!

python學習算法(Python機器學習五十六)1

python學習算法

SciPy提供了FFTpack模塊,包含了傅裡葉變換的算法實現。

傅裡葉變換把信号從時域變換到頻域,以便對信号進行處理。傅裡葉變換在信号與噪聲處理、圖像處理、音頻信号處理等領域得到了廣泛應用。

如需進一步了解傅裡葉變換原理,可以參考相關資料。

快速傅裡葉變換

計算機隻能處理離散信号,使用離散傅裡葉變換(DFT) 是計算機分析信号的基本方法。但是離散傅裡葉變換的缺點是:計算量大,時間複雜度太高,當采樣點數太高的時候,計算緩慢,由此出現了DFT的快速實現,即快速傅裡葉變換fft。

快速傅裡葉變換(FFT)是計算量更小的離散傅裡葉變換的一種實現方法,其逆變換被稱為快速傅裡葉逆變換(IFFT)。

示例

先對數據進行fft變換,然後再ifft逆變換。

import numpy as np #從fftpack中導入fft(快速傅裡葉變化)和ifft(快速傅裡葉逆變換)函數 from scipy.fftpack import fft,ifft #創建一個随機值數組 x = np.array([1.0, 2.0, 1.0, -1.0, 1.5]) #對數組數據進行傅裡葉變換 y = fft(x) print('fft: ') print(y) print('\n') #快速傅裡葉逆變換 yinv = ifft(y) print('ifft: ') print(yinv) print('\n')

輸出

fft: [ 4.5 0.j 2.08155948-1.65109876j -1.83155948 1.60822041j -1.83155948-1.60822041j 2.08155948 1.65109876j] ifft: [ 1. 0.j 2. 0.j 1. 0.j -1. 0.j 1.5 0.j]

可以看到fft,ifft返回的都是複數。ifft返回的結果中,複數的虛部都是0,實部與原始數據x一緻。

這些點的頻率無法計算,因為沒有設置這N個點的時間長度。如不理解,不必深究,後面會介紹。

理解fft變換結果

我們知道,傅裡葉變換把時域信号變為頻域信号。在離散傅裡葉變換中,頻域信号由一系列不同頻率的諧波(頻率成倍數)組成。fft返回值是一個複數數組,每個複數表示一個正弦波。通常一個波形由振幅,相位,頻率三個變量确定,可以從fft的返回值裡,獲取這些信息。

假設a是時域中的周期信号,采樣頻率為Fs,采樣點數為N。如果A[N] = fft(a[N]),返回值A[N]是一個複數數組,其中:

  • A[0]表示頻率為0hz的信号,即直流分量。
  • A[1:N/2]包含正頻率項,A[N/2:]包含負頻率項。正頻率項就是轉化後的頻域信号,通常我們隻需要正頻率項,即前面的n/2項,負頻率項是計算的中間結果(正頻率項的鏡像值)。
  • 每一項的頻率計算:假設A[i]為數組中的元素,表示一個波形,該波形的頻率 = i * Fs / N
  • A[i] = real j * imag,是一個複數,相位就是複數的輻角,相位 = arg(real/imag)
  • 類似的,振幅就是複數的模,振幅 = sqrt(real^2 imag^2)。但是fft的返回值的模是放大值,直流分量的振幅放大了N倍,弦波分量的振幅放大了N/2倍。

頻率分辨率頻率分辨率是離散傅裡葉變換(DFT)頻域相鄰刻度之間的實際頻率之差。采樣時,數據采樣了T秒(T = 采樣點數N / 采樣頻率Fs),信号的成分中周期最大也就是T秒,最低頻率即“基頻”就等于1 / T,也就是Fs / N,這就是頻率分辨率。基頻 = Fs / N,各個諧波的頻率就是 i * Fs / N,這個公式用于計算各個波形的頻率。

示例

import numpy as np from scipy.fftpack import fft # 采樣點數 N = 4000 # 采樣頻率 (根據采樣定理,采樣頻率必須大于信号最高頻率的2倍,信号才不會失真) Fs = 8000 x = np.linspace(0.0, N/Fs, N) # 時域信号,包含:直流分量振幅1.0,正弦波分量頻率100hz/振幅2.0, 正弦波分量頻率150Hz/振幅0.5/相位np.pi y = 1.0 2.0 * np.sin(100.0 * 2.0*np.pi*x) 0.5*np.sin(150.0 * 2.0*np.pi*x np.pi) # 進行fft變換 yf = fft(y) # 獲取振幅,取複數的絕對值,即複數的模 abs_yf = np.abs(yf) # 獲取相位,取複數的角度 angle_y=np.angle(yf) # 直流信号 print('\n直流信号') print('振幅:', abs_yf[0]/N) # 直流分量的振幅放大了N倍 # 100hz信号 index_100hz = 100 * N // Fs # 波形的頻率 = i * Fs / N,倒推計算索引:i = 波形頻率 * N / Fs print('\n100hz波形') print('振幅:', abs_yf[index_100hz] * 2.0/N) # 弦波分量的振幅放大了N/2倍 print('相位:', angle_y[index_100hz]) # 150hz信号 index_150hz = 150 * N // Fs # 波形的頻率 = i * Fs / N,倒推計算索引:i = 波形頻率 * N / Fs print('\n150hz波形') print('振幅:', abs_yf[index_150hz] * 2.0/N) # 弦波分量的振幅放大了N/2倍 print('相位:', angle_y[index_150hz]) print('100hz與150hz相位差:', angle_y[index_150hz] - angle_y[index_100hz]) print('\n')

輸出

直流信号 振幅: 1.0 100hz波形 振幅: 1.9989359813189005 相位: -1.5315264186250062 150hz波形 振幅: 0.5008489983048182 相位: 1.6297011890497097 100hz與150hz相位差: 3.161227607674716

可以看到,正弦波的相位不一定從0開始,但波形之間的相位差确實s約等于一個pi(值跟采樣頻率與采樣點數有關系)。

離散餘弦變換(DCT)

由于許多要處理的信号都是實信号,在使用FFT時,對于實信号,傅立葉變換的共轭對稱性導緻在頻域中有一半的數據冗餘。

離散餘弦變換(DCT)是對實信号定義的一種變換,變換後在頻域中得到的也是一個實信号,相比離散傅裡葉變換DFT而言, DCT可以減少一半以上的計算。DCT還有一個很重要的性質(能量集中特性):大多書自然信号(聲音、圖像)的能量都集中在離散餘弦變換後的低頻部分,因而DCT在(聲音、圖像)數據壓縮中得到了廣泛的使用。由于DCT是從DFT推導出來的另一種變換,因此許多DFT的屬性在DCT中仍然是保留下來的。

SciPy.fftpack中,提供了離散餘弦變換(DCT)與離散餘弦逆變換(IDCT)的實現。

示例

import numpy as np from scipy.fftpack import dct,idct y = dct(np.array([4., 3., 5., 10., 5., 3.])) print(y)

輸出

[ 60. -3.48476592 -13.85640646 11.3137085 6. -6.31319305]

離散餘弦逆變換(idct),是離散餘弦變換(DCT)的反變換。

示例

import numpy as np from scipy.fftpack import dct,idct y = idct(np.array([4., 3., 5., 10., 5., 3.])) print(y)

輸出

[ 39.15085889 -20.14213562 -6.45392043 7.13341236 8.14213562 -3.83035081]

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved