Scipy.fft.fft: примеры (PYTHON)

Практическое применение scipy.fft.fft для спектрального анализа
Раздел: SciPy, Обработка сигналов
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: Анализ спектра аудиосигнала

Пример python
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

Пример python
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: Фильтрация сигнала

Пример python
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

питон scipy.fft.fft function comments

En
Scipy.fft.fft Fast Fourier Transform