python - numpy.fft.fft 和 numpy.fft.fftfreq 有什么区别

标签 python numpy time-series fft

我正在分析时间序列数据,并希望提取 5 个主要频率分量并将其用作训练机器学习模型的特征。我的数据集是 921 x 10080 。每行是一个时间序列,总共有 921 个。

在探索可能的方法时,我遇到了各种函数,包括 numpy.fft.fftnumpy.fft.fftfreqDFT ……我的问题是,这些函数对数据集有什么作用,这些函数之间有什么区别?

对于 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.

但这并没有真正与我交谈,可能是因为我没有信号处理的背景知识。我应该为我的案例使用哪个函数,即。为数据集的每一行提取前 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])

最佳答案

首先需要了解信号有时域和频域表示。下图显示了一些常见的基本信号类型及其时域和频域表示。

enter image description here

请密切注意正弦曲线,我将用它来说明 fft 和 fftfreq 之间的区别。

傅立叶变换是时域和频域表示之间的门户。因此
numpy.fft.fft() - 返回傅立叶变换。这将有实部和虚部。实部和虚部本身并不是特别有用,除非您对围绕数据窗口中心的对称属性(偶数与奇数)感兴趣。
numpy.fft.fftfreq - 以每单位样本间距的周期返回频率仓中心的浮点数组。
numpy.fft.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

关于python - numpy.fft.fft 和 numpy.fft.fftfreq 有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59979354/

相关文章:

python - 如何迭代列表列表,同时将列表中的每个值传递到 API 并在每个列表列表之后暂停?

python - Jupyter - Python 3 内核死亡

python - 在 Keras 中将多个输入样本映射到单个输出样本

python - 数组排序的 f2py 速度

python - 计算一天中每分钟数据帧中有多少行为 "active"的最有效方法是什么?

r - ggplot2 段——x 轴为时间时的方向

python - 如何将表示字节的 Python 字符串转换为实际字节?

python - 从父 bash 脚本中不可用的 Python 创建环境变量

python - 将一长串 0's and 1' 序列转换为 numpy 数组或 pandas 数据帧

python - 如何设置计算移动平均线的开始时间和结束时间?