首页 > 编程语言 >python 实现FFT快速傅立叶变换算法

python 实现FFT快速傅立叶变换算法

时间:2024-08-07 08:59:26浏览次数:18  
标签:fft python DFT FFT 计算 np 傅立叶 numpy

FFT快速傅里叶变换介绍

FFT(快速傅里叶变换)是计算离散傅里叶变换(DFT)及其逆变换的一种高效算法。DFT是一种将信号从时域转换到频域的数学工具,而FFT通过减少计算量来加速这一过程。

FFT的基本思想

FFT利用了DFT中的对称性和周期性,通过分而治之的策略将DFT分解为更小的DFT,从而显著减少计算复杂度。对于长度为N的序列,直接计算DFT的复杂度是O(N^2),而FFT的复杂度可以降低到O(N log N)。

FFT的算法步骤(以Cooley-Tukey算法为例)

选择分解:首先,将N(序列长度)分解为两个较小的因子,通常是选择N的偶数因子。最常见的分解是将N分解为两个相等的因子(即N为2的幂)。

重新排序(位反转):对输入序列进行位反转排序,这是为了将输入序列重新排列成一种便于后续处理的顺序。

蝶形运算:FFT算法的核心是蝶形运算。在蝶形运算中,两个输入(通常来自序列的特定位置)通过一系列乘法和加法操作结合成一个输出。这个过程在算法的不同层级上重复进行。

逐层计算:FFT算法通过逐层(从最低层到最高层)应用蝶形运算来计算DFT。每一层都基于前一层的输出,并且每一层的计算都更加接近最终的DFT结果。

Python FFT快速傅立叶变换

在Python中,实现快速傅里叶变换(FFT)的一种简便方法是使用numpy库中的fft模块。numpy提供了高效的FFT算法实现,能够处理一维或多维数组。

以下是一个简单的例子,展示如何使用numpy中的fft.fft函数来计算一维数组的FFT。

首先,确保你已经安装了numpy库。如果没有安装,可以通过pip安装:

pip install numpy

然后,你可以使用以下Python代码来计算FFT:

import numpy as np
import matplotlib.pyplot as plt

# 创建一个样本信号,例如一个包含正弦波和余弦波的复合信号
Fs = 1000  # 采样频率
T = 1/Fs  # 采样周期
L = 1500  # 信号长度
t = np.linspace(0, L-1, L)*T  # 时间向量

# 创建一个复合信号
S = 0.7*np.sin(2*np.pi*50*t) + np.sin(2*np.pi*120*t)

# 使用numpy的fft函数计算FFT
Y = np.fft.fft(S)

# 获取FFT的频率轴
P2 = np.abs(Y/L)
P1 = P2[:L//2+1]
P1[1:-1] = 2*P1[1:-1]  # 去除对称性
f = Fs*np.arange(0,(L//2+1))/L

# 绘制FFT的幅度谱
plt.figure()
plt.plot(f, P1) 
plt.title('Single-Sided Amplitude Spectrum of S(t)')
plt.xlabel('f (Hz)')
plt.ylabel('|P1(f)|')
plt.show()

在这个例子中,我们首先生成了一个包含两个不同频率正弦波的复合信号S。然后,我们使用numpy.fft.fft函数计算了信号的FFT。为了获得FFT的幅度谱,我们计算了Y的绝对值并除以信号长度L,以得到归一化的幅度。由于FFT的结果是对称的(对于实数输入),我们通常只关注一半的频率范围,并相应地调整幅度(将一半的频率范围中的幅度加倍,除了第一个和最后一个点)。最后,我们使用matplotlib库绘制了FFT的幅度谱。

注意,这个例子仅用于演示如何在Python中使用numpy库进行FFT计算。在实际应用中,你可能需要根据你的具体需求调整信号生成、FFT计算以及结果分析的方式。

FFT(快速傅立叶变换)是一种计算离散傅立叶变换(DFT)的快速算法,用于将信号从时域转换为频域。在Python中,可以使用NumPy库进行FFT的实现。

FFT python样例

下面是一个使用NumPy实现FFT的示例代码:

import numpy as np

def fft(x):
    N = len(x)
    if N <= 1:
        return x
    even = fft(x[0::2])
    odd = fft(x[1::2])
    T = [np.exp(-2j * np.pi * k / N) * odd[k] for k in range(N // 2)]
    return [even[k] + T[k] for k in range(N // 2)] + [even[k] - T[k] for k in range(N // 2)]

# 示例输入信号
x = [0, 1, 2, 3, 4, 5, 6, 7]
# 执行FFT
X = fft(x)
# 输出FFT结果
print(X)

输出结果:

[(28+0j), (-4+9.65685424949238j), (-4+4j), (-4+1.6568542494923806j), (-4+0j), (-4-1.6568542494923806j), (-4-4j), (-4-9.65685424949238j)]

上述代码中的 fft 函数使用递归将输入信号划分为偶数和奇数索引的两个部分,然后再将两部分合并。函数的返回值是FFT变换后的结果。

注意:上述代码是一个简化的FFT实现,不考虑性能优化和处理异常情况。在实际应用中,可以使用NumPy库中的 numpy.fft.fft 函数进行FFT计算,它提供了更高效和稳定的实现。

标签:fft,python,DFT,FFT,计算,np,傅立叶,numpy
From: https://blog.csdn.net/u010634139/article/details/140917144

相关文章

  • 8 Python字符串与二进制文本相互转换
     欢迎来到@一夜看尽长安花博客,您的点赞和收藏是我持续发文的动力对于文章中出现的任何错误请大家批评指出,一定及时修改。有任何想要讨论的问题可联系我:[email protected]。发布文章的风格因专栏而异,均自成体系,不足之处请大家指正。   专栏:java全栈C&C++PythonAIP......
  • 7 Python之代码类型提示(Type Hint)
     欢迎来到@一夜看尽长安花博客,您的点赞和收藏是我持续发文的动力对于文章中出现的任何错误请大家批评指出,一定及时修改。有任何想要讨论的问题可联系我:[email protected]。发布文章的风格因专栏而异,均自成体系,不足之处请大家指正。   专栏:java全栈C&C++PythonAIP......
  • Python 内联函数最佳实践
    如果我有一个可以用一行表示的python函数,那么以下哪一个选项通常被认为最适合可读性和一般最佳实践?或者还有其他更好的选择吗?选项2对我来说似乎是最好的,但我是初学者,所以我不想假设任何事情。我尝试过搜索PEP8、StackOverflow和一两个博客,但我找不到任何关于python的明......
  • 在Python中抽象出具有相同接口的真实硬件和模拟设备
    我正在寻找一种更惯用或更简洁的OOP模式来实现与以下内容等效的功能。接口和实现fromabcimportABC,abstractmethodfromtypingimportoverrideclassDevice:"""Maininterfacethathideswhetherthedeviceisarealhardwaredeviceorasimulated......
  • Python Django,使用外部MSSQL数据库
    我正在尝试创建一个连接到外部MSSQL数据库以仅检索信息(只读)的django网站。这个数据库非常庞大,有数百个表。我目前可以通过在django应用程序中创建一个函数来使其工作,该函数使用connectionString并运行原始SQL查询并将其返回到pandas数据帧中。不知何故,我感觉......
  • 使用 Python 中的 Matplotlib 和时间序列索引生成奇怪的图
    我正在尝试使用Python中的Matplotlib绘制一些时间序列数据,但生成的图看起来很奇怪,我不明白为什么。这是我正在使用的代码:filtered_df=df.loc[(df.index>'2010-01-01')&(df.index<='2010-01-08')]#Plottingthedatafig,axs=plt.subplots(1,1,figsize=(12,......
  • Dash Python:通过 @callback 链接选项卡
    这个问题是下面链接的问题的扩展:DashPython:布局函数中的@Callback未被调用我有一个简单的数据框:importpandasaspddf=pd.DataFrame({'Class1':[1,2,3,4,5],'Class2':[6,7,8,9,10]})我创建了一个数据提取函数,该函数根......
  • 如何在 Python 中使用 Langchain 返回已使用的上下文以进行回答
    我已经构建了一个像这样的RAG系统:defformat_docs(docs):return"\n\n".join(doc.page_contentfordocindocs)response_schemas=[ResponseSchema(name="price",description="Price",type="float"),ResponseSchema(......
  • 如何从 python socket.sendmsg 获取套接字 Tx 时间戳
    在阅读此处、此处和此处时,我发现在Linux系统上,您可以通过设置套接字选项来请求接收和传输的数据包的时间戳。我目前可以使用SO_TIMESTAMPNS和SO_TIMESTAMPING来通过recvmsg获取Rx时间戳。使用sendmsg我不知道......
  • Python 类型注释中“|”两边是否“强制”使用空格?
    “Union运算符”|没有出现在PEP8的其他建议中的“始终被空格包围的运算符”列表中因此,应该可以将其样式设置为类似于算术运算符,并删除圆括号、方括号内的空格,或者如果该运算符比表达式中的其他运算符具有更高的优先级。在我看来,删除空格可以提高表达式......