SciPy Cheatsheet
FFT
Use this SciPy reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
Core Import
from scipy.fft import ( fft, ifft, rfft, irfft, fft2, ifft2, fftn, ifftn, rfft2, rfftn, irfftn, fftfreq, rfftfreq, fftshift, ifftshift, dct, idct, dst, idst, next_fast_len, set_workers ) import numpy as np
Prefer
scipy.fftover the legacyscipy.fftpack(frozen) and overnumpy.fftwhen you need real-input transforms, DCT/DST, multithreading, or better performance on large arrays.
1-D FFT
from scipy.fft import fft, ifft, fftfreq, fftshift # Sample a signal: 2 Hz + 8 Hz sine, fs = 100 Hz fs = 100 t = np.arange(0, 1, 1/fs) x = np.sin(2*np.pi*2*t) + 0.5*np.sin(2*np.pi*8*t) X = fft(x) # complex spectrum, length n freqs = fftfreq(len(x), d=1/fs) # bin frequencies (0, ..., +f, -f, ...) # Amplitude spectrum (one-sided) n = len(x) amp = 2/n * np.abs(X[:n//2]) f_pos = freqs[:n//2] # Center zero frequency for plotting X_shifted = fftshift(X) f_shifted = fftshift(freqs) # Round-trip x_back = ifft(X) # complex; np.real(x_back) recovers x # Zero-padding / truncation via n X = fft(x, n=256) # pad to 256 points
Real-Input FFT (rfft)
from scipy.fft import rfft, irfft, rfftfreq # Real input -> only non-negative frequencies (n//2 + 1 bins), ~2x faster X = rfft(x) # shape (n//2 + 1,) freqs = rfftfreq(len(x), d=1/fs) x_back = irfft(X, n=len(x)) # pass n for odd-length signals
Always use
rfftfor real signals — half the memory, no redundant negative frequencies, andirfftreturns a real array directly.
N-D FFT
from scipy.fft import fft2, ifft2, fftn, ifftn, fftshift img = np.random.rand(256, 256) F = fft2(img) # 2-D FFT F_centered = fftshift(F) # DC component to center power = np.abs(F_centered)**2 # power spectrum img_back = np.real(ifft2(F)) # Arbitrary dimensions / axes F = fftn(volume) # all axes F = fftn(arr, axes=(0, 1)) # only some axes
DCT & DST
from scipy.fft import dct, idct, dst, idst x = np.array([1.0, 2.0, 1.0, -1.0, 1.5]) # Discrete cosine transform (type 2 is the default, the "JPEG" DCT) y = dct(x, type=2, norm='ortho') x_back = idct(y, type=2, norm='ortho') # Discrete sine transform y = dst(x, type=2, norm='ortho')
Use
norm='ortho'to make the transform orthonormal soidct(dct(x))round-trips without scale factors.
Performance
from scipy.fft import fft, fftn, next_fast_len, set_workers # FFT is fastest on sizes that factor into small primes n = len(x) n_fast = next_fast_len(n) # smallest fast size >= n X = fft(x, n=n_fast) # zero-pad to a fast length # Multithreaded transforms X = fft(big_array, workers=4) # per-call with set_workers(4): # scoped default X = fftn(volume)
Convolution via FFT
from scipy.signal import fftconvolve, oaconvolve # Fast convolution of long signals (uses scipy.fft internally) y = fftconvolve(sig, kernel, mode='same') # Overlap-add: best when one input is much longer than the other y = oaconvolve(long_sig, short_kernel, mode='same')
Common Gotchas
fftoutput is unnormalized. Divide byn(and multiply single-sided amplitudes by 2) to recover physical amplitudes; or passnorm='ortho'for a symmetric 1/√n convention on both directions.
Spectral leakage: an FFT assumes the signal is periodic in the window. Apply a window (
scipy.signal.get_window('hann', n)) before the FFT for non-periodic data.
irfftneedsnfor odd lengths.irfft(rfft(x))returns an even-length array by default — passirfft(X, n=len(x))to round-trip odd-length signals exactly.
Frequency ordering: raw
fftoutput is [0, positive freqs, negative freqs]. Usefftshift+fftshift(fftfreq(n, d))before plotting, orrfft/rfftfreqto avoid negative bins entirely.