从 x-y 点列表中进行离散傅里叶变换

11

我想要做的是,从具有周期模式的x-y点列表中计算周期。凭借我的有限数学知识,我知道傅里叶变换可以做到这种事情。

我正在编写Python代码。

我在这里找到了一个相关的答案(链接),但它使用一个均匀分布的x轴,即dt是固定的,这对我来说并不适用。由于我实际上不太理解其背后的数学原理,所以我不确定它是否会在我的代码中正常工作。

我的问题是,它能行吗?或者,是否有numpy中已经完成我的工作的方法?或者,我该如何做?

编辑:所有值都是Pythonic float(即双精度)。


你能发布这个列表吗? - Moritz
@Moritz 不完全是这样...它包含成千上万的点...绘制出来后,会有明显的周期性模式。 - Michael Kim
然后至少发布情节,这样我们就知道你正在处理什么... - Spektre
插值和重新采样数据可能是一种解决方案。我已经在这里提供了一个示例:https://dev59.com/sV8e5IYBdhLWcg3wdqGT#53772921。 - Foad S. Farimani
3个回答

16

对于不均匀间隔的样本,您可以使用scipy.signal.lombscargle来计算朗伯-斯卡格尔周期图。以下是一个示例,其中信号的主频率为2.5 rad/s。

from __future__ import division

import numpy as np
from scipy.signal import lombscargle
import matplotlib.pyplot as plt


np.random.seed(12345)

n = 100
x = np.sort(10*np.random.rand(n))
# Dominant periodic signal
y = np.sin(2.5*x)  
# Add some smaller periodic components
y += 0.15*np.cos(0.75*x) + 0.2*np.sin(4*x+.1)
# Add some noise
y += 0.2*np.random.randn(x.size)

plt.figure(1)
plt.plot(x, y, 'b')
plt.xlabel('x')
plt.ylabel('y')
plt.grid()

dxmin = np.diff(x).min()
duration = x.ptp()
freqs = np.linspace(1/duration, n/duration, 5*n)
periodogram = lombscargle(x, y, freqs)

kmax = periodogram.argmax()
print("%8.3f" % (freqs[kmax],))

plt.figure(2)
plt.plot(freqs, np.sqrt(4*periodogram/(5*n)))
plt.xlabel('Frequency (rad/s)')
plt.grid()
plt.axvline(freqs[kmax], color='r', alpha=0.25)
plt.show()
脚本打印出2.497并生成以下图表:

plot of the signal

plot of the Lomb-Scargle periodogram


不确定在这里使用 from __future__ import division 是做什么的?但是我似乎不需要它。 - Michael Kim
@MichaelKim 这是我经常使用Python 2和Python 3的习惯。目前这个脚本不需要那个导入,但如果你改变了脚本,比如说duration变成了一个大于1的整数,那么如果没有导入division,表达式1/duration将会是0。另一种“版本兼容”的方法是将表达式更改为1.0/duration,但我正在逐渐习惯Python 3的风格,所以我使用了division的导入。 - Warren Weckesser
我有点晚了,但是y轴的单位是什么?类似于功率谱,是原始单位的平方吗? - Wolfmercury

1
作为起点:
  • (我假设所有坐标都是正整数,否则将它们映射到合理的范围,如0..4095)
  • 在列表中找到最大的坐标xMax,yMax
  • 制作一个二维数组,其维度为yMax,xMax
  • 用零填充它
  • 遍历您的列表,将对应于坐标的数组元素设置为1
  • 进行二维傅里叶变换
  • 查找FT结果中的特殊点(峰值)

什么是坐标范围? - MBo

0

1
这些是用于等间距样本的。 - Warren Weckesser
似乎不能处理浮点数值,只适用于整数。 - Michael Kim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接