Python'da hızlı bir Fourier dönüşümü çizme


95

NumPy ve SciPy'ye erişimim var ve bir veri kümesinin basit bir FFT'sini oluşturmak istiyorum. Biri ydeğerler ve diğeri bu ydeğerler için zaman damgaları olan iki listem var .

Bu listeleri bir SciPy veya NumPy yöntemine beslemenin ve ortaya çıkan FFT'yi çizmenin en basit yolu nedir?

Örneklere baktım, ancak hepsi belirli sayıda veri noktası ve sıklığı vb. İle bir dizi sahte veri oluşturmaya dayanıyor ve yalnızca bir veri kümesi ve karşılık gelen zaman damgalarıyla bunun nasıl yapılacağını gerçekten göstermiyor .

Aşağıdaki örneği denedim:

from scipy.fftpack import fft

# Number of samplepoints
N = 600

# Sample spacing
T = 1.0 / 800.0
x = np.linspace(0.0, N*T, N)
y = np.sin(50.0 * 2.0*np.pi*x) + 0.5*np.sin(80.0 * 2.0*np.pi*x)
yf = fft(y)
xf = np.linspace(0.0, 1.0/(2.0*T), N/2)
import matplotlib.pyplot as plt
plt.plot(xf, 2.0/N * np.abs(yf[0:N/2]))
plt.grid()
plt.show()

Fakat fftveri setime argümanını değiştirdiğimde ve grafiğini çizdiğimde, son derece garip sonuçlar alıyorum ve görünen o ki, frekans için ölçeklendirme kapalı olabilir. Emin değilim

İşte FFT'ye çalıştığım verilerin bir pastebin'i

http://pastebin.com/0WhjjMkb http://pastebin.com/ksM4FvZS

Her şeyi kullandığımda fft(), sıfırda büyük bir artış var ve başka hiçbir şey yok.

İşte kodum:

## Perform FFT with SciPy
signalFFT = fft(yInterp)

## Get power spectral density
signalPSD = np.abs(signalFFT) ** 2

## Get frequencies corresponding to signal PSD
fftFreq = fftfreq(len(signalPSD), spacing)

## Get positive half of frequencies
i = fftfreq>0

##
plt.figurefigsize = (8, 4));
plt.plot(fftFreq[i], 10*np.log10(signalPSD[i]));
#plt.xlim(0, 100);
plt.xlabel('Frequency [Hz]');
plt.ylabel('PSD [dB]')

Aralık sadece eşittir xInterp[1]-xInterp[0].


bize neyi denediğinizi, nasıl başarısız olduğunu ve üzerinde çalıştığınız örnekleri gösterin.
Paul H

Denediğim örneği ve onun hakkında düşündüğüm şeyi yayınladım, sanırım çıktının nasıl doğru şekilde çizileceğine dair kafam karıştı.
user3123955

bu harika bir örnek, ama sorun tam olarak nedir? bu kod benim için harika çalışıyor. arsa basitçe görünmüyor mu?
Paul H

yani, ne tür argümanlar kullanıyorsunuz (verilerinizin en azından bir kısmını görmemiz gerekiyor)
Paul H

x ve y ekseninin pastebin'ini ekledim, x verisi saniye cinsindendir ve y verisi sadece bir sensör okumasıdır. Bu veri listelerini fft örneğine
koyduğumda

Yanıtlar:


99

Bu yüzden bir IPython not defterinde kodunuzun işlevsel olarak eşdeğer bir biçimini çalıştırıyorum:

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import scipy.fftpack

# Number of samplepoints
N = 600
# sample spacing
T = 1.0 / 800.0
x = np.linspace(0.0, N*T, N)
y = np.sin(50.0 * 2.0*np.pi*x) + 0.5*np.sin(80.0 * 2.0*np.pi*x)
yf = scipy.fftpack.fft(y)
xf = np.linspace(0.0, 1.0/(2.0*T), N/2)

fig, ax = plt.subplots()
ax.plot(xf, 2.0/N * np.abs(yf[:N//2]))
plt.show()

Makul olduğuna inandığım çıktıyı elde ediyorum.

görüntü açıklamasını buraya girin

Mühendislik okulunda sinyal işleme hakkında düşündüğümden beri kabul ettiğimden uzun sürdü, ancak 50 ve 80'deki artışlar tam olarak beklediğim şey. Peki sorun nedir?

Yayınlanan ham verilere ve yorumlara yanıt olarak

Buradaki sorun, periyodik verilerinizin olmamasıdır. Uygun olduğundan emin olmak için her zaman herhangi bir algoritmaya beslediğiniz verileri incelemelisiniz .

import pandas
import matplotlib.pyplot as plt
#import seaborn
%matplotlib inline

# the OP's data
x = pandas.read_csv('http://pastebin.com/raw.php?i=ksM4FvZS', skiprows=2, header=None).values
y = pandas.read_csv('http://pastebin.com/raw.php?i=0WhjjMkb', skiprows=2, header=None).values
fig, ax = plt.subplots()
ax.plot(x, y)

görüntü açıklamasını buraya girin


1
Örnek yanlış değil, onu nasıl alacağımı ve verilerime nasıl uygulayacağımı bilmediğimden.
user3123955

@ user3123955, doğru. bu nedenle verilerinizi ve size yardım edecekseniz nasıl başarısız olacağını görmemiz gerekiyor.
Paul H

pastebin'i ekledim
user3123955

2
@ user3123955 peki herhangi bir FFT algoritmasının bu konuda ne yapmasını bekliyorsunuz? verilerinizi temizlemeniz gerekir.
Paul H

6
@PaulH frekansta genlik olmamalıdır 50 Hzolmak 1ve frekansta 80 Hzolacak 0.5?
Furqan Hashim

24

Fft ile ilgili önemli olan şey, yalnızca zaman damgasının tekdüze olduğu verilere uygulanabilmesidir ( yani , yukarıda gösterdiğiniz gibi , zaman içinde tek tip örnekleme).

Tek tip olmayan örnekleme durumunda, lütfen verileri sığdırmak için bir işlev kullanın. Aralarından seçim yapabileceğiniz birkaç öğretici ve işlev vardır:

https://github.com/tiagopereira/python_tips/wiki/Scipy%3A-curve-fitting http://docs.scipy.org/doc/numpy/reference/generated/numpy.polyfit.html

Sığdırma bir seçenek değilse, verileri tek tip bir örneklemeye enterpolasyon yapmak için doğrudan bir tür enterpolasyon kullanabilirsiniz:

https://docs.scipy.org/doc/scipy-0.14.0/reference/tutorial/interpolate.html

Tek tip numuneleriniz olduğunda, numunelerinizin sadece delta ( t[1] - t[0]) zamanı hakkında kafa yormanız gerekecektir . Bu durumda, doğrudan fft işlevlerini kullanabilirsiniz.

Y    = numpy.fft.fft(y)
freq = numpy.fft.fftfreq(len(y), t[1] - t[0])

pylab.figure()
pylab.plot( freq, numpy.abs(Y) )
pylab.figure()
pylab.plot(freq, numpy.angle(Y) )
pylab.show()

Bu probleminizi çözmeli.


2
Verilerimi eşit aralıklarla hesapladım, fftfreq'in tam olarak ne yaptığını söyleyebilir misiniz? neden x eksenime ihtiyaç duyuyor? neden Y'nin absini ve açısını çiziyorsunuz? Açı faz mı? Aşama neye göre? Bunu verilerimle yaptığımda, 0Hz'de dev bir zirveye sahip ve çok hızlı bir şekilde kayboluyor, ancak onu sabit bir ofseti olmayan verileri besliyorum (0.15 Gz ila 12Hz arası kenarlara sahip veriler üzerinde büyük bir bant geçişi yapıyorum sabit ofsetten kurtulmak için verilerim 4 Hz'den büyük olmamalı, bu yüzden bant bilgi kaybetmeme neden olmalı).
user3123955

2
1. fftfreqsize verilerinize karşılık gelen frekans bileşenlerini verir. Grafiği çizerseniz freq, x ekseninin sürekli artan bir fonksiyon olmadığını göreceksiniz. X ekseninde doğru frekans bileşenlerine sahip olduğunuzdan emin olmalısınız. Kılavuza
ssm

2
2. Çoğu insan fft'nin büyüklüğüne ve aşamasına bakmaktan hoşlanır. Faz bilgisinin size ne söyleyeceğini tek bir cümleyle açıklamak zor, ancak tek söyleyebileceğim, sinyalleri birleştirdiğinizde anlamlı olduğudur. Faz içi olan aynı frekanstaki sinyalleri birleştirdiğinizde, bunlar 180 derece faz dışı kaldıklarında zayıflayacaklardır. Bu, amplifikatörleri veya geri bildirimi olan herhangi bir sistemi tasarladığınızda önemli hale gelir.
ssm

2
3. Genel olarak, en düşük frekansınız pratik olarak sıfır faza sahip olacaktır ve bu, buna atıfta bulunur. Sinyaller sisteminizde hareket ettiğinde, her frekans farklı bir hızla hareket eder. Bu faz hızıdır. Faz grafiği size bu bilgiyi verir. Ne ile çalıştığınızı bilmiyorum, bu yüzden size kesin bir cevap veremem. Bu tür sorular için, geri besleme kontrolü, analog elektronik, dijital sinyal işleme, elektromanyetik alan teorisi vb. Veya sisteminize daha özel bir şey hakkında bilgi almak daha iyidir.
ssm

4
Kullanmaktan daha 4. Aksine sizin verilerinizi, neden kendi sinyalleri üreterek başlayın Yüklü: t = linspace(0, 10, 1000); ys = [ (1.0/i)*sin(i*t) for i in arange(10)]; y = reduce(lambda m, n: m+n, ys). Sonra her birini ysve toplamını çizin yve her bileşenin fft değerini alın. Programlamanızla güven kazanacaksınız. Sonra sonucunuzun gerçekliğini yargılayabilirsiniz.
Analiz

12

Sahip olduğunuz yüksek artış, sinyalinizin DC (değişken olmayan, yani frek = 0) kısmından kaynaklanmaktadır. Bu bir ölçek meselesi. DC olmayan frekans içeriğini görmek istiyorsanız, görselleştirme için, sinyalin FFT'sinin ofset 0'ından değil, ofset 1'den çizim yapmanız gerekebilir.

Yukarıda verilen örneği @PaulH ile değiştirmek

import numpy as np
import matplotlib.pyplot as plt
import scipy.fftpack

# Number of samplepoints
N = 600
# sample spacing
T = 1.0 / 800.0
x = np.linspace(0.0, N*T, N)
y = 10 + np.sin(50.0 * 2.0*np.pi*x) + 0.5*np.sin(80.0 * 2.0*np.pi*x)
yf = scipy.fftpack.fft(y)
xf = np.linspace(0.0, 1.0/(2.0*T), N/2)

plt.subplot(2, 1, 1)
plt.plot(xf, 2.0/N * np.abs(yf[0:N/2]))
plt.subplot(2, 1, 2)
plt.plot(xf[1:], 2.0/N * np.abs(yf[0:N/2])[1:])

Çıktı grafikleri: DC ile FFT sinyalini çizme ve sonra onu kaldırırken (freq = 0 atlama)

Diğer bir yol, verileri günlük ölçeğinde görselleştirmektir:

Kullanarak:

plt.semilogy(xf, 2.0/N * np.abs(yf[0:N/2]))

Gösterecek: görüntü açıklamasını buraya girin


Evet, Hz. Kodunda, tanımı xffrekanslarına fft bidonları eşler.
hesham_EE

1
Güzel! Peki ya y ekseni? Genlik? Çok teşekkür ederim hesham_EE
Victor Aguiar

Evet, y ekseni karmaşık fft'nin mutlak değeridir. Kullanımına dikkat edinnp.abs()
hesham_EE

8

Daha önce verilen cevapların bir tamamlayıcısı olarak, FFT için genellikle kutuların boyutuyla oynamanın önemli olduğunu belirtmek isterim. Bir grup değeri test etmek ve uygulamanız için daha anlamlı olanı seçmek mantıklı olacaktır. Genellikle, numune sayısı ile aynı büyüklüktedir. Bu, verilen cevapların çoğunun varsaydığı gibi, harika ve makul sonuçlar veriyor. Biri bunu keşfetmek isterse, işte kod sürümüm:

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import scipy.fftpack

fig = plt.figure(figsize=[14,4])
N = 600           # Number of samplepoints
Fs = 800.0
T = 1.0 / Fs      # N_samps*T (#samples x sample period) is the sample spacing.
N_fft = 80        # Number of bins (chooses granularity)
x = np.linspace(0, N*T, N)     # the interval
y = np.sin(50.0 * 2.0*np.pi*x) + 0.5*np.sin(80.0 * 2.0*np.pi*x)   # the signal

# removing the mean of the signal
mean_removed = np.ones_like(y)*np.mean(y)
y = y - mean_removed

# Compute the fft.
yf = scipy.fftpack.fft(y,n=N_fft)
xf = np.arange(0,Fs,Fs/N_fft)

##### Plot the fft #####
ax = plt.subplot(121)
pt, = ax.plot(xf,np.abs(yf), lw=2.0, c='b')
p = plt.Rectangle((Fs/2, 0), Fs/2, ax.get_ylim()[1], facecolor="grey", fill=True, alpha=0.75, hatch="/", zorder=3)
ax.add_patch(p)
ax.set_xlim((ax.get_xlim()[0],Fs))
ax.set_title('FFT', fontsize= 16, fontweight="bold")
ax.set_ylabel('FFT magnitude (power)')
ax.set_xlabel('Frequency (Hz)')
plt.legend((p,), ('mirrowed',))
ax.grid()

##### Close up on the graph of fft#######
# This is the same histogram above, but truncated at the max frequence + an offset. 
offset = 1    # just to help the visualization. Nothing important.
ax2 = fig.add_subplot(122)
ax2.plot(xf,np.abs(yf), lw=2.0, c='b')
ax2.set_xticks(xf)
ax2.set_xlim(-1,int(Fs/6)+offset)
ax2.set_title('FFT close-up', fontsize= 16, fontweight="bold")
ax2.set_ylabel('FFT magnitude (power) - log')
ax2.set_xlabel('Frequency (Hz)')
ax2.hold(True)
ax2.grid()

plt.yscale('log')

çıktı grafikleri: görüntü açıklamasını buraya girin


5

Gerçek sinyallerin FFT'sini çizmekle ilgilenen bir işlev oluşturdum. Yukarıdaki mesajlara göre benim fonksiyonumdaki ekstra bonus, sinyalin GERÇEK genliğini almanızdır. Ayrıca, gerçek bir sinyal varsayımı nedeniyle, FFT simetriktir, bu nedenle x ekseninin yalnızca pozitif tarafını çizebiliriz:

import matplotlib.pyplot as plt
import numpy as np
import warnings


def fftPlot(sig, dt=None, plot=True):
    # here it's assumes analytic signal (real signal...)- so only half of the axis is required

    if dt is None:
        dt = 1
        t = np.arange(0, sig.shape[-1])
        xLabel = 'samples'
    else:
        t = np.arange(0, sig.shape[-1]) * dt
        xLabel = 'freq [Hz]'

    if sig.shape[0] % 2 != 0:
        warnings.warn("signal prefered to be even in size, autoFixing it...")
        t = t[0:-1]
        sig = sig[0:-1]

    sigFFT = np.fft.fft(sig) / t.shape[0]  # divided by size t for coherent magnitude

    freq = np.fft.fftfreq(t.shape[0], d=dt)

    # plot analytic signal - right half of freq axis needed only...
    firstNegInd = np.argmax(freq < 0)
    freqAxisPos = freq[0:firstNegInd]
    sigFFTPos = 2 * sigFFT[0:firstNegInd]  # *2 because of magnitude of analytic signal

    if plot:
        plt.figure()
        plt.plot(freqAxisPos, np.abs(sigFFTPos))
        plt.xlabel(xLabel)
        plt.ylabel('mag')
        plt.title('Analytic FFT plot')
        plt.show()

    return sigFFTPos, freqAxisPos


if __name__ == "__main__":
    dt = 1 / 1000

    # build a signal within nyquist - the result will be the positive FFT with actual magnitude
    f0 = 200  # [Hz]
    t = np.arange(0, 1 + dt, dt)
    sig = 1 * np.sin(2 * np.pi * f0 * t) + \
        10 * np.sin(2 * np.pi * f0 / 2 * t) + \
        3 * np.sin(2 * np.pi * f0 / 4 * t) +\
        7.5 * np.sin(2 * np.pi * f0 / 5 * t)

    # res in freqs
    fftPlot(sig, dt=dt)
    # res in samples (if freqs axis is unknown)
    fftPlot(sig)

analitik FFT grafiği sonucu


4

Bu sayfada zaten harika çözümler var, ancak hepsi veri kümesinin tek tip / eşit olarak örneklendiğini / dağıtıldığını varsaydı. Rastgele örneklenmiş verilerin daha genel bir örneğini sunmaya çalışacağım. Bu MATLAB dersini de örnek olarak kullanacağım :

Gerekli modülleri eklemek:

import numpy as np
import matplotlib.pyplot as plt
import scipy.fftpack
import scipy.signal

Örnek verilerin oluşturulması:

N = 600 # number of samples
t = np.random.uniform(0.0, 1.0, N) # assuming the time start is 0.0 and time end is 1.0
S = 1.0 * np.sin(50.0 * 2 * np.pi * t) + 0.5 * np.sin(80.0 * 2 * np.pi * t) 
X = S + 0.01 * np.random.randn(N) # adding noise

Veri kümesinin sıralanması:

order = np.argsort(t)
ts = np.array(t)[order]
Xs = np.array(X)[order]

Yeniden örnekleme:

T = (t.max() - t.min()) / N # average period 
Fs = 1 / T # average sample rate frequency
f = Fs * np.arange(0, N // 2 + 1) / N; # resampled frequency vector
X_new, t_new = scipy.signal.resample(Xs, N, ts)

verileri ve yeniden örneklenen verileri çizme:

plt.xlim(0, 0.1)
plt.plot(t_new, X_new, label="resampled")
plt.plot(ts, Xs, label="org")
plt.legend()
plt.ylabel("X")
plt.xlabel("t")

görüntü açıklamasını buraya girin

şimdi fft hesaplanıyor:

Y = scipy.fftpack.fft(X_new)
P2 = np.abs(Y / N)
P1 = P2[0 : N // 2 + 1]
P1[1 : -2] = 2 * P1[1 : -2]

plt.ylabel("Y")
plt.xlabel("f")
plt.plot(f, P1)

görüntü açıklamasını buraya girin

Not: Sonunda eşit olmayan bir şekilde dağıtılmış verilerin Fourier dönüşümünü elde etmek için daha kanonik bir algoritma uygulamak için zaman buldum. Kodu, açıklamayı ve örnek Jupyter not defterini burada görebilirsiniz .


Dokümanlarda, tek tip resampleolmayan örnek zamanların işlendiğini gösteren hiçbir şey görmüyorum . Bir zaman parametresini (örnekte kullanılmayan) kabul eder, ancak bu aynı zamanda tek tip örnek zamanları da varsayar.
user2699

@ user2699 bu örnek yardımcı olabilir
Foad

@ user2699 Kodu düzenledi. Bir göz atıp sorun olup olmadığını bana bildirirseniz sevinirim.
Foad

1
'scipy.signal.resample`, verileri yeniden örneklemek için FFT yöntemini kullanır. Tek tip bir FFT elde etmek için tek tip olmayan verileri yeniden örneklemek için kullanmanın bir anlamı yoktur.
user2699

1
Verdiğiniz tüm yöntemlerin avantajları ve dezavantajları vardır (bunun sklearn.utils.resampleenterpolasyon yapmadığını unutmayın ). Düzensiz olarak örneklenmiş bir sinyalin frekanslarını bulmak için mevcut seçenekleri veya farklı enterpolasyon türlerinin yararlarını tartışmak isterseniz, lütfen başka bir soru başlatın. Her ikisi de ilginç konular, ancak bir FFT'nin nasıl planlanacağına dair cevapların kapsamının çok ötesinde.
user2699

4

Bu ek cevabı fft kullanırken sivri uçların yayılmasının kökenlerini açıklamak için yazıyorum ve özellikle bir noktada katılmadığım scipy.fftpack öğreticisini tartışıyorum .

Bu örnekte kayıt süresi tmax=N*T=0.75. Sinyal sin(50*2*pi*x)+0.5*sin(80*2*pi*x). Frekans sinyali, frekanslarda 50ve 80amplitüdlerde 1ve 0.5. Bununla birlikte, analiz edilen sinyalde tam sayı periyot sayısı yoksa, sinyalin kesilmesi nedeniyle difüzyon ortaya çıkabilir:

  • Pike 1: 50*tmax=37.5=> frekans 50, 1/tmax=> Bu frekanstaki sinyal kesilmesinden dolayı difüzyonun bir katı değildir .
  • Pike 2: 80*tmax=60=> frekans 80, 1/tmax=> Bu frekanstaki sinyal kesilmesinden dolayı difüzyonun bir katıdır .

İşte öğreticide ( sin(50*2*pi*x)+0.5*sin(80*2*pi*x)) aynı sinyali analiz eden ancak küçük farklılıklar içeren bir kod :

  1. Orijinal scipy.fftpack örneği.
  2. Tam sayı sinyal periyotları içeren orijinal scipy.fftpack örneği ( kesilme difüzyonunu önlemek tmax=1.0yerine 0.75).
  3. Tam sayı sinyal periyotları içeren ve tarihlerin ve frekansların FFT teorisinden alındığı orijinal scipy.fftpack örneği.

Kod:

import numpy as np
import matplotlib.pyplot as plt
import scipy.fftpack

# 1. Linspace
N = 600
# sample spacing
tmax = 3/4
T = tmax / N # =1.0 / 800.0
x1 = np.linspace(0.0, N*T, N)
y1 = np.sin(50.0 * 2.0*np.pi*x1) + 0.5*np.sin(80.0 * 2.0*np.pi*x1)
yf1 = scipy.fftpack.fft(y1)
xf1 = np.linspace(0.0, 1.0/(2.0*T), N//2)

# 2. Integer number of periods
tmax = 1
T = tmax / N # sample spacing
x2 = np.linspace(0.0, N*T, N)
y2 = np.sin(50.0 * 2.0*np.pi*x2) + 0.5*np.sin(80.0 * 2.0*np.pi*x2)
yf2 = scipy.fftpack.fft(y2)
xf2 = np.linspace(0.0, 1.0/(2.0*T), N//2)

# 3. Correct positionning of dates relatively to FFT theory (arange instead of linspace)
tmax = 1
T = tmax / N # sample spacing
x3 = T * np.arange(N)
y3 = np.sin(50.0 * 2.0*np.pi*x3) + 0.5*np.sin(80.0 * 2.0*np.pi*x3)
yf3 = scipy.fftpack.fft(y3)
xf3 = 1/(N*T) * np.arange(N)[:N//2]

fig, ax = plt.subplots()
# Plotting only the left part of the spectrum to not show aliasing
ax.plot(xf1, 2.0/N * np.abs(yf1[:N//2]), label='fftpack tutorial')
ax.plot(xf2, 2.0/N * np.abs(yf2[:N//2]), label='Integer number of periods')
ax.plot(xf3, 2.0/N * np.abs(yf3[:N//2]), label='Correct positionning of dates')
plt.legend()
plt.grid()
plt.show()

Çıktı:

Burada olabileceği gibi, tamsayı sayıda periyot kullanılsa bile bir miktar difüzyon kalır. Bu davranış, scipy.fftpack öğreticisindeki tarihlerin ve sıklıkların kötü konumlandırılmasından kaynaklanmaktadır. Bu nedenle, ayrık Fourier dönüşümleri teorisinde:

  • sinyal, t=0,T,...,(N-1)*TT'nin örnekleme periyodu ve sinyalin toplam süresinin olduğu tarihlerde değerlendirilmelidir tmax=N*T. Durduğumuzu unutmayın tmax-T.
  • ilişkili frekanslar , örnekleme frekansının f=0,df,...,(N-1)*dfolduğu yerdir df=1/tmax=1/(N*T). Yayılmayı önlemek için sinyalin tüm harmonikleri örnekleme frekansının çok katı olmalıdır.

Yukarıdaki örnekte, arangeyerine kullanımının linspacefrekans spektrumunda ek difüzyonu önlemeyi sağladığını görebilirsiniz . Dahası, linspaceversiyonun kullanılması, aynı zamanda, olması gerekenden biraz daha yüksek frekanslarda bulunan sivri uçların kaymasına da yol açar, bu sivri uçların frekansların biraz sağında olduğu ilk resimde görüldüğü gibi 50ve 80.

Sadece kullanım örneğinin aşağıdaki kodla değiştirilmesi gerektiği sonucuna varacağım (ki bu benim görüşüme göre daha az yanıltıcıdır):

import numpy as np
from scipy.fftpack import fft
# Number of sample points
N = 600
T = 1.0 / 800.0
x = T*np.arange(N)
y = np.sin(50.0 * 2.0*np.pi*x) + 0.5*np.sin(80.0 * 2.0*np.pi*x)
yf = fft(y)
xf = 1/(N*T)*np.arange(N//2)
import matplotlib.pyplot as plt
plt.plot(xf, 2.0/N * np.abs(yf[0:N//2]))
plt.grid()
plt.show()

Çıktı (ikinci artış artık dağınık değil):

Bence bu yanıt, ayrık Fourier dönüşümünün doğru şekilde nasıl uygulanacağına dair bazı ek açıklamalar getirmeye devam ediyor. Açıkçası, cevabım çok uzun ve her zaman söylenecek ek şeyler var (@ewerlopes örneğin kısaca takma addan bahsetti ve pencereleme hakkında çok şey söylenebilir ) bu yüzden duracağım. Bunu uygularken ayrık Fourier dönüşümü ilkelerini derinlemesine anlamanın çok önemli olduğunu düşünüyorum çünkü hepimiz istediklerini elde etmek için onu uygularken buraya ve oraya faktör ekleyen çok fazla insan biliyoruz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.