我正在研究神经元群体的模拟,我想从它们的局部场势中提取主要频率.它的形式只有一个值的向量,我已经在这里绘制了它.显然,有一些振荡活动正在发生,我对大规模振荡发生的频率感兴趣.

Plot of LFP for a simulation

除了傅里叶变换的一般概念外,我对它们不是很熟悉,但我相信它们是这里所需的工具?该仿真的采样距离为0.00006秒,采样率为1/0.00006赫兹.我try 使用numpy.fft.fft函数,但我有点不确定如何解释结果.我预计在1附近会有一个很大的峰值,对应于看起来像是1赫兹的振荡.下面是我运行的代码和结果图.

raw = np.loadtxt(r"./file.txt")

#calculate the frequencies associated with our signal
freqs = fft.rfftfreq(len(raw),0.0006)
sp = fft.rfft(raw)

plt.plot(freqs, sp.real, freqs, sp.imag)

Entire FFT plot

我认为高采样率导致了计算如此高的频率,我知道我只对~0-4赫兹的频率感兴趣,因此我可以将其绘制为:

0-4 Hz FFT plot

或者为了使其更容易可视化,只需约1-4赫兹:

~1-4 Hz FFT plot

请注意,我计算FFTs并没有什么不同,只是绘制了结果的不同区域.我的问题是我不清楚如何解释结果,或者如何意识到我在代码中的某个地方犯了错误.我可以在结果中看到一些峰值,但它们没有达到我预期的水平,我也不确定如何确定它们何时显著.

任何在这方面的帮助都是值得感激的.:^)

推荐答案

为什么你找不到1点的峰值

只是为了用我自己的方式重现可能的问题

import numpy as np
import matplotlib.pyplot as plt
# time with a 0.00006 second per sample
t=np.arange(0,12,0.00006)
# y is roughly sin(2π.f.t)⁴. But with some noise.
# Because of power 4, it is a 2f periodic signal. So I choose f 
# around 0.5 to mimic the 1Hz signal. And I choose not exactly 0.5
# but a more specific 0.47, to verify my ability to find it back
y=(np.sin(2*np.pi*0.47*t)+np.random.normal(0,0.1,(len(t),)))**4 

plt.plot(t,y)
plt.show()

enter image description here

不是相同的信号,但足够接近演示目的.

现在,你所做的是

freqs = np.fft.rfftfreq(len(y),0.0006)
sp = np.fft.rfft(y)

Which gives (once zoomed on the interesting part) enter image description here

值较大时为0,因为信号平均不为0(这是常量项,或0 HZ)

另一个在0.1之前(我们推测是0.094).在0.2之前有一个小的(第一谐波).

然后,因为你确定1之前的任何东西都应该被忽略(但为什么?即使没有错误,如果FFT告诉你最大的峰值是0.1赫兹,那么为什么会这样呢? ,你放大了大的平面0区域.由于噪音,随着变焦,没有什么是真正平坦的.

你应该做的是

freqs = np.fft.rfftfreq(len(y),0.00006)

注意这对fft没有任何影响.fft行甚至没有使用freqs作为参数.只有在绘图时,它才改变x轴上的指示.同样的情节.只是x轴上的刻度不同.

enter image description here

(我没有花很多精力来进行完全相同的zoom ,因为我是用鼠标做的.但你可以看到,它是一样的,除了以前的0.1是现在的1)

更准确的估计

你可能已经注意到,我们所看到的是FFT中的峰值略低于1.可能是我的0.94.但很难说是0.94,0.96... 因为它在低频下的分辨率非常低. (第一个频率是0.08333……那是一个12秒的周期,整个跨度.秒是它的两倍,所以时间是6秒.等. 在0.91666和1之间没有freqs%的频率.很难从中准确地找到0.94%).

在这里,我觉得你更多地是在寻找一个重复周期,而不是一个频率(你可能会说,同样的事情.但在FFT中,重点是提供能够再现信号的周期函数的基.而不是映射所有频率.对于高频来说,这几乎是一样的,因为那里的分辨率很高.但对于低频率/高周期,情况并非如此).

所以我宁愿在这里找到最好的自相关.例如,简单地使用卷积

conv=np.convolve(y,y[::-1])

It gives you this enter image description here

当然,有趣的是这里的山峰. 当信号与自身最匹配时,它们就会出现(想想打印在2个透明图形上的信号).你们互相推搡).

在这里,我们还没有为新的矢量基数固定基频.单位是"样本". 我大致看到的是第二个峰值的位置,在17760. (中间的那个是当y与自身匹配时,根本没有移位.然后每个峰值都有1,2,3的位移,...或者-1,-2,-3...句号) 17760*0.06等于1.0596秒. 所以1/1.0596=0.94赫兹...

Python相关问答推荐

Pandas 填充条件是另一列

Python会扔掉未使用的表情吗?

我在使用fill_between()将最大和最小带应用到我的图表中时遇到问题

Pandas 在最近的日期合并,考虑到破产

根据另一列中的nan重置值后重新加权Pandas列

Pytest两个具有无限循环和await命令的Deliverc函数

如何删除索引过go 的lexsort深度可能会影响性能?' &>

抓取rotowire MLB球员新闻并使用Python形成表格

使用索引列表列表对列进行切片并获取行方向的向量长度

使可滚动框架在tkinter环境中看起来自然

avxspan与pandas period_range

DataFrames与NaN的条件乘法

在Python 3中,如何让客户端打开一个套接字到服务器,发送一行JSON编码的数据,读回一行JSON编码的数据,然后继续?

Gekko中基于时间的间隔约束

如何在FastAPI中替换Pydantic的constr,以便在BaseModel之外使用?'

在Python中控制列表中的数据步长

解决Geopandas和Altair中的正图和投影问题

Polars表达式无法访问中间列创建表达式

具有不匹配列的2D到3D广播

对于数组中的所有元素,Pandas SELECT行都具有值