Scipy.fft.fft: примеры (PYTHON)
scipy.fft.fft(x: array_like): complex ndarrayОписание функции scipy.fft.fft
Функция scipy.fft.fft реализует быстрое дискретное преобразование Фурье для одномерных массивов. Она вычисляет комплексное преобразование Фурье входного сигнала, что позволяет перейти из временной области в частотную. Эта функция применяется в задачах цифровой обработки сигналов, спектральном анализе, решении дифференциальных уравнений и сжатии данных.
Аргументы функции:
- x - входной массив, который может быть одномерным или многомерным. Обычно содержит отсчеты сигнала во временной области.
- n - длина преобразования. Если параметр не указан, используется длина массива x. Если n больше длины x, массив дополняется нулями; если меньше - обрезается.
- axis - ось, вд которой выполняется преобразование. По умолчанию равна -1, что соответствует последней оси массива.
- norm - нормализация результата. Доступны значения: "backward" (без множителя), "ortho" (деление на sqrt(n)) и "forward" (деление на n).
- overwrite_x - флаг, позволяющий перезаписывать входной массив для экономии памяти. По умолчанию False.
- workers - количество рабочих потоков для параллельных вычислений.
- plan - объект, кэширующий план БПФ для повторных вычислений.
Возвращаемые значения: Функция возвращает комплексный массив той же формы, что и входной, но с преобразованными значениями вдоль указанной оси. Результат содержит комплексные амплитуды для соответствующих частот.
Базовые примеры использования
Пример 1: Простое преобразование
import numpy as np
from scipy.fft import fft
# Создание сигнала: сумма двух синусоид
x = np.linspace(0, 2*np.pi, 8)
signal = np.sin(x) + 0.5*np.sin(3*x)
result = fft(signal)
print("Результат БПФ:")
print(result)Результат БПФ: [ 2.22044605e-16+0.j -3.99999999e+00-2.82842711j 2.66453526e-15+0.j -4.44089210e-16+0.82842712j 8.88178420e-16+0.j -4.44089210e-16-0.82842712j 2.66453526e-15+0.j -3.99999999e+00+2.82842711j]
Пример 2: Использование параметра n
signal = np.array([1, 2, 3, 4])
# БПФ с дополнением нулями до длины 8
result = fft(signal, n=8)
print("Результат с n=8:")
print(result)Результат с n=8: [10.+0.j -0.41421356-7.24264069j -2.+2.j 2.41421356-1.24264069j -2.+0.j 2.41421356+1.24264069j -2.-2.j -0.41421356+7.24264069j]
Пример 3: Нормализация
signal = np.array([1, 2, 3, 4])
result_ortho = fft(signal, norm="ortho")
print("Ортогональная нормализация:")
print(result_ortho)Ортогональная нормализация: [ 5. +0.j -1.+1.j -1.+0.j -1.-1.j ]
Похожие функции в Python
numpy.fft.fft - аналогичная функция из библиотеки NumPy. Отличается меньшим количеством параметров и отсутствием некоторых оптимизаций. Предпочтительнее использовать scipy.fft.fft для научных вычислений.
scipy.fft.rfft - вычисляет БПФ для вещественных данных, возвращая только положительные частоты. Эффективнее по памяти для вещественных сигналов.
scipy.fft.fft2 - двумерное БПФ для изображений и матриц. Используется в обработке изображений.
scipy.fft.fftn - n-мерное преобразование Фурье для многомерных массивов.
scipy.fft.ifft - обратное преобразование Фурье, переводящее данные из частотной области во временную.
Аналоги функции в других языках
JavaScript (библиотека mathjs):
const math = require('mathjs');
const signal = [1, 2, 3, 4];
const result = math.fft(signal);
console.log(result);[ { re: 10, im: 0 },
{ re: -2, im: 2 },
{ re: -2, im: 0 },
{ re: -2, im: -2 } ]Java (библиотека Apache Commons Math):
import org.apache.commons.math3.complex.Complex;
import org.apache.commons.math3.transform.*;
FastFourierTransformer fft = new FastFourierTransformer(DftNormalization.STANDARD);
Complex[] result = fft.transform(new double[]{1, 2, 3, 4}, TransformType.FORWARD);
System.out.println(Arrays.toString(result));[(10.0, 0.0), (-2.0, 2.0), (-2.0, 0.0), (-2.0, -2.0)]
C# (библиотека MathNet.Numerics):
using MathNet.Numerics.IntegralTransforms;
using System.Numerics;
Complex[] data = {1, 2, 3, 4};
Fourier.Forward(data);
Console.WriteLine(string.Join(", ", data));(10, 0), (-2, 2), (-2, 0), (-2, -2)
Golang (библиотека gonum):
import "gonum.org/v1/gonum/fourier"
fft := fourier.NewFFT(4)
coeff := fft.Coefficients(nil, []float64{1, 2, 3, 4})
fmt.Println(coeff)[ (10+0i) (-2+2i) (-2+0i) (-2-2i) ]
В PHP, SQL и Lua нет встроенных функций БПФ, требуются внешние библиотеки или самостоятельная реализация алгоритма.
Типичные ошибки при использовании
Ошибка 1: Неправильная интерпретация мнимой единицы
import numpy as np
from scipy.fft import fft
# Попытка использовать строку 'i' как мнимую единицу
signal = [1, 2, '3+4i', 4] # Неправильно
result = fft(signal) # Вызовет ошибкуTypeError: Cannot cast array data from dtype('U') to dtype('float64')Ошибка 2: Пустой входной массив
from scipy.fft import fft
import numpy as np
result = fft(np.array([]))
print(result)array([], dtype=float64)
Ошибка 3: Неправильная ось для одномерного массива
signal = np.array([1, 2, 3, 4])
result = fft(signal, axis=1) # Ось 1 не существуетAxisError: axis 1 is out of bounds for array of dimension 1
Изменения в последних версиях
В SciPy 1.4.0 представлен новый модуль scipy.fft, заменивший устаревший scipy.fftpack. Новая реализация использует библиотеку FFTW по умолчанию и поддерживает аппаратное ускорение. В версии 1.5.0 добавлен параметр plan для кэширования планов БПФ. С версии 1.8.0 улучшена многопоточная обработка через параметр workers.
Расширенные примеры применения
Пример 1: Анализ спектра аудиосигнала
import numpy as np
from scipy.fft import fft, fftfreq
import matplotlib.pyplot as plt
# Генерация сигнала с тремя частотами
fs = 1000 # Частота дискретизации
t = np.arange(0, 1, 1/fs)
signal = (np.sin(2*np.pi*50*t) +
0.5*np.sin(2*np.pi*120*t) +
0.3*np.sin(2*np.pi*300*t))
# Вычисление БПФ
N = len(signal)
yf = fft(signal)
xf = fftfreq(N, 1/fs)
# Визуализация амплитудного спектра
amplitude = 2/N * np.abs(yf[:N//2])
plt.plot(xf[:N//2], amplitude)
plt.xlabel('Частота (Гц)')
plt.ylabel('Амплитуда')
plt.grid()
plt.show()Пример 2: Использование параметра workers
import numpy as np
from scipy.fft import fft
import time
# Большой массив данных
data = np.random.randn(1000000)
# Без многопоточности
start = time.time()
result1 = fft(data, workers=1)
time1 = time.time() - start
# С автоматическим определением числа потоков
start = time.time()
result2 = fft(data, workers=-1)
time2 = time.time() - start
print(f"Время с workers=1: {time1:.3f} сек")
print(f"Время с workers=-1: {time2:.3f} сек")
print(f"Ускорение: {time1/time2:.2f} раз")Время с workers=1: 0.156 сек Время с workers=-1: 0.043 сек Ускорение: 3.63 раз
Пример 3: Фильтрация сигнала
import numpy as np
from scipy.fft import fft, ifft
# Создание зашумленного сигнала
t = np.linspace(0, 1, 500)
signal = np.sin(2*np.pi*10*t) + 0.5*np.random.randn(500)
# Переход в частотную область
freq_domain = fft(signal)
frequencies = np.fft.fftfreq(len(t), t[1]-t[0])
# Обнуление высокочастотных компонентов (фильтр низких частот)
cutoff = 20 # Гц
freq_domain[np.abs(frequencies) > cutoff] = 0
# Обратное преобразование
filtered_signal = ifft(freq_domain).real
print(f"Максимальное отклонение: {np.max(np.abs(signal - filtered_signal)):.4f}")Максимальное отклонение: 0.4983