在Python中将FFT绘制为一组正弦波?

2023-11-25

我在演示中看到有人这样做,但我很难重现他能够做到的事情。这是他演讲中的一张幻灯片:

Sinewave decomposition via FFT

很酷。他使用 FFT 分解数据集,然后绘制 FFT 指定的适当正弦波。

因此,为了重现他所做的事情,我创建了一系列对应于 2 个正弦波组合的点:

import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline

x = np.arange(0, 10, 0.01)
x2 = np.arange(0, 20, 0.02)
sin1 = np.sin(x)
sin2 = np.sin(x2)
x2 /= 2
sin3 = sin1 + sin2
plt.plot(x, sin3)
plt.show()

Composed wave

现在我想将这个波(或者更确切地说,这些点暗示的波)分解回原来的 2 个正弦波:

# goal: sin3 -> sin1, sin2
# sin3 
array([ 0.00000000e+00,  2.99985000e-02,  ... 3.68998236e-01])
# sin1 
array([ 0.        ,  0.00999983,  0.01999867,  ... -0.53560333])
# sin2 
array([ 0.        ,  0.01999867,  0.03998933, ... 0.90460157])

我从导入开始numpy并得到fft of sin3:

import numpy as np
fft3 = np.fft.fft(sin3)

好吧,据我所知,这就是了。现在我有一个包含复数的数组:

array([ 2.13316069e+02+0.00000000e+00j,  3.36520138e+02+4.05677438e+01j,...])

如果我天真地绘制它,我会看到:

plt.plot(fft3)
plt.show()

fft naively plotted

好吧,不知道该怎么办。

我想从这里获取看起来像 sin1 和 sin2 的数据集:

plt.plot(sin1)
plt.show()

sin1 data plotted

plt.plot(sin2)
plt.show()

sin2 data plotted

我理解复数的实部和虚部fft3数据集,我只是不确定如何处理它们来导出sin1 and sin2从中获取数据集。

我知道这与编程关系不大,与数学关系更大,但有人可以在这里给我提示吗?

编辑:更新马克·斯奈德的答案:

使用马克的代码,我能够得到我所期望的结果,并最终得到了这个方法:

def decompose_fft(data: list, threshold: float = 0.0):
    fft3 = np.fft.fft(data)
    x = np.arange(0, 10, 10 / len(data))
    freqs = np.fft.fftfreq(len(x), .01)
    recomb = np.zeros((len(x),))
    for i in range(len(fft3)):
        if abs(fft3[i]) / len(x) > threshold:
            sinewave = (
                1 
                / len(x) 
                * (
                    fft3[i].real 
                    * np.cos(freqs[i] * 2 * np.pi * x) 
                    - fft3[i].imag 
                    * np.sin(freqs[i] * 2 * np.pi * x)))
            recomb += sinewave
            plt.plot(x, sinewave)
    plt.show()

    plt.plot(x, recomb, x, data)
    plt.show()

稍后我会让它返回重新组合的波浪列表,但现在我遇到了一个我不太明白的异常情况。首先,我这样称呼它,只需传入一个数据集。

decompose_fft(sin3, threshold=0.0)

但看起来不错,但我得到了这条奇怪的线y=0.2有谁知道这可能是什么或是什么原因造成的?

Looks really good

EDIT:

上述问题已由Mark在评论中解答,谢谢!


离散傅里叶变换给出复指数的系数,当它们相加时,产生原始的离散信号。特别是,第 k 个傅里叶系数为您提供有关在给定数量的样本上具有 k 个周期的正弦曲线幅度的信息。

请注意,由于您的正弦在 1000 个样本中没有整数个周期,因此您实际上无法使用 FFT 检索原始正弦波。相反,您将得到许多不同正弦曲线的混合,包括 ~.4 的恒定分量。

您可以使用以下代码绘制各个正弦波分量并观察它们的总和是原始信号:

freqs = np.fft.fftfreq(len(x),.01)
threshold = 0.0
recomb = np.zeros((len(x),))
for i in range(len(fft3)):
    if abs(fft3[i])/(len(x)) > threshold:
        recomb += 1/(len(x))*(fft3[i].real*np.cos(freqs[i]*2*np.pi*x)-fft3[i].imag*np.sin(freqs[i]*2*np.pi*x))
        plt.plot(x,1/(len(x))*(fft3[i].real*np.cos(freqs[i]*2*np.pi*x)-fft3[i].imag*np.sin(freqs[i]*2*np.pi*x)))
plt.show()

plt.plot(x,recomb,x,sin3)
plt.show()

通过改变threshold,您还可以选择排除低功率的正弦曲线,看看它如何影响最终的重建。

编辑:上面的代码中有一点陷阱,尽管它没有错误。它隐藏了真实信号 DFT 的固有对称性,并以真实幅度的一半绘制每个正弦曲线两次。此代码性能更高,并以正确的幅度绘制正弦曲线:

import cmath

freqs = np.fft.fftfreq(len(x),.01)
threshold = 0.0
recomb = np.zeros((len(x),))
middle = len(x)//2 + 1
for i in range(middle):
    if abs(fft3[i])/(len(x)) > threshold:
        if i == 0:
            coeff = 2
        else:
            coeff = 1
        sinusoid = 1/(len(x)*coeff/2)*(abs(fft3[i])*np.cos(freqs[i]*2*np.pi*x+cmath.phase(fft3[i])))
        recomb += sinusoid
        plt.plot(x,sinusoid)
plt.show()

plt.plot(x,recomb,x,sin3)
plt.show()

如果在一般情况下,您知道信号由某些正弦波子集组成,其频率可能与信号长度不正确对齐,则您可以通过零填充或扩展信号来识别频率。您可以了解更多相关信息here。如果信号完全是任意的,并且您只是对查看正弦波分量感兴趣,则无需这样做。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在Python中将FFT绘制为一组正弦波? 的相关文章

随机推荐

  • Ninject 和 ASP.NET Web API

    在我提出问题之前 您应该知道我从此页面获取了当前的代码 http www strathweb com 2012 05 using ninject with the latest asp net web api source 我正在尝试通过使
  • 在模板函数中包装 std::format 无法使用最新的 MSVC 编译器更新进行编译

    我有点困惑为什么这段代码突然停止编译 https godbolt org z hhM5GG78x 但如果我将编译器改回 v19 31 它将编译 https godbolt org z 11j8WbEzG 这是有问题的代码 include
  • 如何使用 LINQ 从字符串中删除字符

    我有一个像这样的字符串 XQ74MNT8244A 我需要删除所有char从字符串中 所以输出会像 748244 这个怎么做 请帮我做到这一点 new string XQ74MNT8244A Where char IsDigit ToArra
  • Redis 和 Membase 之间的主要区别是什么?

    Redis 和 Membase 之间的主要区别是什么 可扩展性 Membase 提供分布式键 值存储 就像 Memcache 一样 因此无论数据集有多大 写入和读取都将始终在可预测的恒定时间内执行 另一方面 Redis 只提供主从复制 可以
  • 当页面为 HTTPS 时 URLReferrer 为 null

    我们使用 URLReferrer 和在查询字符串中传递的代码来生成在线视频 以便只有我们的付费客户才能链接到我们的视频播放页面 该系统已经运行良好一段时间了 我知道 URL 引荐来源网址可能会被欺骗 但谁会告诉他们的客户做这样的事情来访问视
  • 使用字典替换文本文件中的单词

    我正在尝试打开一个文本文件 然后通读它 用存储在字典中的字符串替换某些字符串 根据以下问题的答案如何在 Python 中编辑文本文件 我可以在进行替换之前取出字典值 但循环字典似乎更有效 该代码不会产生任何错误 但也不会进行任何替换 imp
  • Node.js 中的 New Date() 时间错误

    考虑 root ubuntu firma Exotech heart beat heart beat service date Mon Apr 24 17 07 52 CEST 2017 root ubuntu firma Exotech
  • RabbitMQ 向每个消费者发送相同的消息

    我已经实现了 RabbitMQ 网站上的示例 RabbitMQ 示例 我已将其扩展为带有一个用于发送消息的按钮的应用程序 现在我在两台不同的计算机上启动了两个消费者 当我发送消息时 第一条消息发送到computer1 然后第二条消息发送到c
  • 如何使用 Javascript 动态嵌入 Java 小程序?

    我希望能够使用按下按钮时调用的 Javascript 函数动态地将 Java 小程序插入网页中 在页面加载时加载小程序会减慢速度太多 冻结浏览器等 我使用以下代码 它在 FF 中无缝工作 但在 IE8 Safari 4 和 Chrome 中
  • 简单 CRUD 的 EJB 3 会话 Bean 设计

    我正在编写一个应用程序 其唯一目的是执行 CRUD 操作以维护数据库中的记录 一些表 实体之间存在关系 我见过的创建会话 bean 的大多数示例都涉及与许多我没有的实体交互的复杂业务逻辑 操作 由于我的应用程序非常基础 那么会话 bean
  • Spring Boot Oauth2 扩展 DefaultTokenServices

    我有一个 OAuth2 实现 对于授予类型 密码运行良好 现在我需要添加一个逻辑 如果用户之前登录 则限制相同的用户 密码组合允许再次登录 为此 我研究并认为我要创建一个扩展 DefaultTokenServices 类的新类 MyDefa
  • 覆盖 Angular 默认日期管道

    我需要覆盖默认的 Angular 7 日期管道格式 medium short fullDate等 因为我不想使用两个日期管道 默认一个和自定义一个 所以我做了以下操作 并且想知道这样做是个好主意 extend date pipe ts im
  • 如何在/proc/driver下创建proc条目?

    我想在 a 下创建一个文件 proc driver目录 我想使用像这样的宏proc root driver 或提供的其他内容 而不是显式使用 driver MODULE NAME 我用create proc entry struct pro
  • 使用 IsCancellationRequested 属性?

    有什么用CancellationToken s IsCancellationRequested财产 考虑下面的代码 static void Main string args CancellationTokenSource tokenSour
  • 二叉搜索树的平均高度

    添加 1000 个随机整数时 如何计算二叉搜索树的平均高度 平均身高是多少 这个问题让我问你是否可以在不实际生成树的情况下最终解决这个问题 我设法编写了一个应用程序 如果您将 N 个唯一数字的所有可能排列添加到一个简单实现的二叉树中 它可以
  • 从 python 列表项中删除单引号

    其实很简单的问题 我有一个 python 列表 例如 1 2 3 4 只是想知道如何去掉那些单引号 我想 1 2 3 4 目前列表中的所有值都是字符串 而您希望它们是整数 以下是两种最简单的方法 map int your list and
  • 自定义按钮框架看起来不如圆形矩形 UIButton

    我正在尝试绘制自定义按钮框架 如下所示 UIBezierPath stroke UIBezierPath bezierPathWithRoundedRect self bounds cornerRadius RECT CORNECR RAD
  • 使用 Python 请求发送 ASP.net POST

    我正在使用 Python 的请求模块抓取一个旧的 ASP net 网站 我花了 5 个多小时试图弄清楚如何模拟这个 POST 请求 但没有成功 按照我下面的方式执行此操作 我基本上会收到一条消息 没有项目与此项目引用匹配 任何帮助将不胜感激
  • 协议相关 URL 是相对 URL 吗?

    所以考虑一个协议相关 URL像这样 www example com file jpg 从我记事起 我脑子里就一直有这样的想法 协议相对 URL 实际上是绝对 URL 它们的行为与绝对 URL 完全相同 但绝不像相对 URL 那样工作 我不希
  • 在Python中将FFT绘制为一组正弦波?

    我在演示中看到有人这样做 但我很难重现他能够做到的事情 这是他演讲中的一张幻灯片 很酷 他使用 FFT 分解数据集 然后绘制 FFT 指定的适当正弦波 因此 为了重现他所做的事情 我创建了一系列对应于 2 个正弦波组合的点 import m