В чем разница между numpy .fft.fft и numpy .fft.fftfreq - PullRequest
0 голосов
/ 30 января 2020

Я анализирую данные временных рядов и хотел бы выделить 5 основных частотных компонентов и использовать их в качестве функций для обучения модели машинного обучения. Мой набор данных 921 x 10080. Каждая строка является временным рядом, и их всего 921.

Исследуя возможные способы сделать это, я столкнулся с различными функциями, включая numpy.fft.fft, numpy.fft.fftfreq и DFT ... My Вопрос в том, что эти функции делают с набором данных и в чем разница между этими функциями?

Для Numpy.fft.fft, Numpy Состояние документа:

Compute the one-dimensional discrete Fourier Transform.

This function computes the one-dimensional n-point discrete Fourier Transform (DFT) with the efficient Fast Fourier Transform (FFT) algorithm [CT].

В то время как для numpy.fft.fftfreq:

numpy.fft.fftfreq(n, d=1.0)
Return the Discrete Fourier Transform sample frequencies.

The returned float array f contains the frequency bin centers in cycles per unit of the sample spacing (with zero at the start). For instance, if the sample spacing is in seconds, then the frequency unit is cycles/second.

Но на самом деле это не говорит со мной, вероятно, потому что у меня нет базовых знаний для обработки сигналов. Какую функцию я должен использовать для моего случая, ie. извлечь первые 5 основных частотных и амплитудных компонентов для каждого ряда набора данных? Спасибо


Обновление:

Использование fft вернул результат ниже. Я намеревался получить первые 5 значений частоты и амплитуды для каждого временного ряда, но являются ли они частотными составляющими?

Вот код:

def get_fft_values(y_values, T, N, f_s):
    f_values = np.linspace(0.0, 1.0/(2.0*T), N//2)
    fft_values_ = rfft(y_values)
    fft_values = 2.0/N * np.abs(fft_values_[0:N//2])
    return f_values[0:5], fft_values[0:5]  #f_values - frequency(length = 5040) ; fft_values - amplitude (length = 5040)

t_n = 1
N = 10080
T = t_n / N
f_s = 1/T

result = pd.DataFrame(df.apply(lambda x: get_fft_values(x, T, N, f_s), axis =1)) 
result

и вывод

0   ([0.0, 1.000198452073824, 2.000396904147648, 3.0005953562214724, 4.000793808295296], [52.91299603174603, 1.2744877093061115, 2.47064631896607, 1.4657299825335832, 1.9362280837538701])
1   ([0.0, 1.000198452073824, 2.000396904147648, 3.0005953562214724, 4.000793808295296], [57.50430555555556, 4.126212552498241, 2.045294347349226, 0.7878668631936439, 2.6093502232989976])
2   ([0.0, 1.000198452073824, 2.000396904147648, 3.0005953562214724, 4.000793808295296], [52.05765873015873, 0.7214089616631307, 1.8547819994826562, 1.3859749465142301, 1.1848485830307878])
3   ([0.0, 1.000198452073824, 2.000396904147648, 3.0005953562214724, 4.000793808295296], [53.68928571428572, 0.44281647644149114, 0.3880646059685434, 2.3932194091895043, 0.22048418335196407])
4   ([0.0, 1.000198452073824, 2.000396904147648, 3.0005953562214724, 4.000793808295296], [52.049007936507934, 0.08026717757664162, 1.122163085234073, 1.2300320578011028, 0.01109727616896663])
... ...
916 ([0.0, 1.000198452073824, 2.000396904147648, 3.0005953562214724, 4.000793808295296], [74.39303571428572, 2.7956204803382096, 1.788360577194303, 0.8660509272194551, 0.530400826933975])
917 ([0.0, 1.000198452073824, 2.000396904147648, 3.0005953562214724, 4.000793808295296], [51.88751984126984, 1.5768804453161231, 0.9932384706239461, 0.7803585797514547, 1.6151532436755451])
918 ([0.0, 1.000198452073824, 2.000396904147648, 3.0005953562214724, 4.000793808295296], [52.16263888888889, 1.8672674706267687, 0.9955183554654834, 1.0993971449470716, 1.6476405255363171])
919 ([0.0, 1.000198452073824, 2.000396904147648, 3.0005953562214724, 4.000793808295296], [59.22579365079365, 2.1082518972190183, 3.686245044113031, 1.6247500816133893, 1.9790245755039324])
920 ([0.0, 1.000198452073824, 2.000396904147648, 3.0005953562214724, 4.000793808295296], [59.32333333333333, 4.374568790482763, 1.3313693716184536, 0.21391538068483704, 1.414774377287436])

Ответы [ 2 ]

2 голосов
/ 30 января 2020

Если под «основным компонентом» вы подразумеваете 5 самых сильных частот, вы будете искать эти значения в результате np.fft.fft(). Чтобы узнать, к каким частотам относятся эти значения, вы будете использовать np.fft.fftfreq. выходные данные обоих будут массивами одинаковой длины, таким образом, вы можете подать свои индексы из np.fft.fft() в массив из np.fft.fftfreq(), чтобы получить соответствующую частоту.

Например, например, вывод fft равен A и fftfreq - это B, предположим, что A [1] - это один из ваших основных компонентов, B [1] = 0 Гц - это частота вашего основного компонента.

1 голос
/ 30 января 2020

Прежде всего необходимо понять, что существуют представления сигналов во временной и частотной областях. Графики c ниже показывают несколько распространенных основных типов сигналов и их представления во временной и частотной областях.

enter image description here

Обратите особое внимание на синусоидальную кривую, которую я буду использовать для иллюстрации разницы между fft и fftfreq.

Преобразование Фурье это портал между вашим временным доменом и представлением частотного домена. Следовательно,

numpy.fft.fft() - возвращает преобразование Фурье. это будет иметь как реальные, так и мнимые части. Реальные и мнимые части сами по себе не особенно полезны, если только вы не заинтересованы в свойствах симметрии вокруг центра окна данных (четные и нечетные).

numpy.fft.fftfreq - возвращает массив с плавающей точкой Частотные интервалы центрируются в циклах на единицу интервала выборки.

Метод numpy.fft.fft() - это способ получить правильную частоту, которая позволяет правильно разделить БПФ.

Это лучше всего проиллюстрировано с примером:

import numpy as np
import matplotlib.pyplot as plt

#fs is sampling frequency
fs = 100.0
time = np.linspace(0,10,int(10*fs),endpoint=False)

#wave is the sum of sine wave(1Hz) and cosine wave(10 Hz)
wave = np.sin(np.pi*time)+ np.cos(np.pi*time)
#wave = np.exp(2j * np.pi * time )

plt.plot(time, wave)
plt.xlim(0,10)
plt.xlabel("time (second)")
plt.title('Original Signal in Time Domain')

plt.show()

Signal in time domain

# Compute the one-dimensional discrete Fourier Transform.

fft_wave = np.fft.fft(wave)

# Compute the Discrete Fourier Transform sample frequencies.

fft_fre = np.fft.fftfreq(n=wave.size, d=1/fs)

plt.subplot(211)
plt.plot(fft_fre, fft_wave.real, label="Real part")
plt.xlim(-50,50)
plt.ylim(-600,600)
plt.legend(loc=1)
plt.title("FFT in Frequency Domain")

plt.subplot(212)
plt.plot(fft_fre, fft_wave.imag,label="Imaginary part")
plt.legend(loc=1)
plt.xlim(-50,50)
plt.ylim(-600,600)
plt.xlabel("frequency (Hz)")

plt.show()

enter image description here

...