此文为翻译+自己的理解,github地址:https://github.com/paulvangentcom/heartrate_analysis_python

对于求心率的信号,我们主要关注心跳之间的间隔及其随时间的变化。我们想要所有R波(R1,R2,... Rn)的位置、它们之间的间隔(RR1,RR2,... RRn,定义为)以及相邻间隔之间的差异(定义为:RRdiff-1,…RRdiff-n)。

频域方面
      在心率信号的频率方面,最常发现的测量方法称为HF(高频),MF(中频)和LF(低频)频段。MF和HF频段通常合并在一起,并被标记为“ HF”。LF和HF大致对应于LF频段的0.04-0.15Hz和HF频段的0.16-0.5Hz。LF频段似乎与短期血压变化有关,HF频段与呼吸频率有关。
      通过在RR间隔序列上执行快速傅立叶变换来计算频谱。顾名思义,该方法与离散傅立叶变换方法相比是快速的。数据集越大,方法之间的速度差异就越大。
我们将首先对信号进行重新采样,以计算频谱,然后将重新采样的信号转换到频域,然后以给定的间隔积分曲线下的面积,从而计算出HF和LF的量度。

时域方面
查看上述时间序列度量,我们需要一些成分才能轻松计算所有这些度量:

  • 所有R峰的位置;
  • 所有RR间隔(RR1,RR2,.. RR-n);
  • RR间隔之间的差异(RRdiff1,…RRdiffn);
  • RR间隔之间连续差的平方根

我们已经从第一部分的detect_peaks()函数获得了所有R峰位置的列表,存储在dict ['peaklist']中calc_RR()函数计算RR间隔,存在dict ['RR_list']中。为了获得最后两个成分,我们使用dict ['RR_list']并计算差值和相邻值之间的平方差:

RR_diff = []
RR_sqdiff = []
RR_list = measures['RR_list']
cnt = 1 #用这个变量迭代RR_listwhile (cnt < (len(RR_list)-1)): #只有有RR间隔就会一直循环RR_diff.append(abs(RR_list[cnt] - RR_list[cnt+1])) #计算连续R-R间隔之间的绝对差RR_sqdiff.append(math.pow(RR_list[cnt] - RR_list[cnt+1], 2)) #计算平方差cnt += 1print(RR_diff, RR_sqdiff)

计算时域度
现在可以轻松计算所有度量值:

ibi = np.mean(RR_list) #RR间隔求均值
print("IBI:", ibi)sdnn = np.std(RR_list) #RR间隔的标准差
print("SDNN:", sdnn)sdsd = np.std(RR_diff) #RR_diff的标准差
print("SDSD:", sdsd)rmssd = np.sqrt(np.mean(RR_sqdiff)) #RR_sqdiff均值的根方
print("RMSSD:", rmssd)nn20 = [x for x in RR_diff if (x>20)] #First create a list of all values over 20, 50
nn50 = [x for x in RR_diff if (x>50)]
pnn20 = float(len(NN20)) / float(len(RR_diff)) #计算NN20,NN50间隔占所有间隔的比例
pnn50 = float(len(NN50)) / float(len(RR_diff)) #Note the use of float(), because we don't want Python to think we want an int() and round the proportion to 0 or 1
print("pNN20, pNN50:", pnn20, pnn50)

将这些计算继续封装,可以这样使用它:

import heartbeat as hb #Assuming we named the file 'heartbeat.py'dataset = hb.get_data('data.csv')hb.process(dataset, 0.75, 100)
#The module dict now contains all the variables computed over our signal:
hb.measures['bpm']
hb.measures['ibi']
hb.measures['sdnn']
#etcetera
#Remember that you can get a list of all dictionary entries with "keys()":
print(hb.measures.keys())

频域度量
       我们想要将心率信号转换到频域(这样做只会返回等于BPM / 60(以Hz表示的心跳)的强频率)。相反,我们希望将RR间隔转换到频域。很难理解?这样思考:随着身体需求的变化,心率随着时间的变化而变化。这种变化表现为心跳之间的距离随时间变化(我们之前计算的RR间隔)。RR峰之间的距离随其自身频率随时间变化。为了可视化,绘制我们之前计算的RR间隔:

从图中可以清楚地看到,RR间隔不会随心跳而剧烈变化,而是随时间呈正弦波状变化(更准确地说是不同正弦波的组合)。我们想找到组成该模式的频率。
       但是,任何傅立叶变换方法都依赖于均匀间隔的数据,并且我们的RR间隔在时间上肯定不是均匀间隔的。这是因为间隔的时间位置取决于它们的长度,每个间隔都不同。我希望这是有道理的。
要实现我们的想法,我们需要:

  • 创建一个带有RR间隔的均匀间隔的时间线;
  • 内插信号,既可以创建均匀间隔的时间序列,又可以提高分辨率;
    • 在某些研究中,此插值步骤也称为重新采样。
  • 将信号转换到频域;
  • 对频谱的LF和HF部分下方的面积进行积分。

计算频域量度
      首先,我们为RR间隔创建均匀间隔的时间线。为此,我们获取所有R峰的样本位置,这些样本位置位于我们在第1部分中计算的列表dict ['peaklist']中。然后,后,我们从列表dict [‘RR_list’]中将y值分配给这些样本位置,该列表包含所有R-R间隔的持续时间。最后,我们对信号进行插值。

from scipy.interpolate import interp1d #从SciPy导入插值函数peaklist = measures['peaklist'] RR_list = measures['RR_list']
RR_x = peaklist[1:] #没有用第一项,因为第一间隔被分配给第二拍。
RR_y = RR_list #Y值等于间隔长度
RR_x_new = np.linspace(RR_x[0],RR_x[-1],RR_x[-1]) #Create evenly spaced timeline starting at the second peak, its endpoint and length equal to position of last peak
f = interp1d(RR_x, RR_y, kind='cubic') #使用三次样条插值对信号进行插值

请注意,时间序列不是从第一个峰值开始,而是从第二个R峰值的采样位置开始。因为我们使用间隔,所以第一个间隔在第二个峰值可用。
       现在,我们可以使用创建的函数f()查找信号范围内任何x位置的y值:

这样,我们可以将整个时间序列RR_x_new传递给函数并进行绘制:

plt.title("Original and Interpolated Signal")
plt.plot(RR_x, RR_y, label="Original", color='blue')
plt.plot(RR_x_new, f(RR_x_new), label="Interpolated", color='red')
plt.legend()
plt.show()

现在,要查找组成插值信号的频率,请使用numpy的快速傅立叶变换np.fft.fft()方法,计算采样间隔,将采样点转换为Hz并作图:

#设置变量
n = len(dataset.hart) #信号长度
frq = np.fft.fftfreq(len(dataset.hart), d=((1/fs))) #转换为频率信息
frq = frq[range(n/2)] #得到单边频率范围#进行 FFT
Y = np.fft.fft(f(RR_x_new))/n # FFT计算
Y = Y[range(n/2)] #返回单边FFT#Plot
plt.title("Frequency Spectrum of Heart Rate Variability")
plt.xlim(0,0.6) #限制X轴中感兴趣的频率范围 (0-0.6Hz可见, 我们对0.04-0.5感兴趣)
plt.ylim(0, 50) #限制Y轴范围
plt.plot(frq, abs(Y)) #Plot it
plt.xlabel("Frequencies in Hz")
plt.show()

真好!您可以清楚地看到信号中的LF和HF频率峰值。
       剩下的最后一件事是对LF(0.04 – 0.15Hz)和HF(0.16 – 0.5Hz)频带下的曲线下面积进行积分。我们需要找到与我们感兴趣的频率范围相对应的数据点。在FFT期间,我们计算了单侧频率范围frq,因此我们可以在其中搜索所需的数据点位置。

lf = np.trapz(abs(Y[(frq>=0.04) & (frq<=0.15)])) #使用NumPy的梯形积分函数来查找面积
print("LF:", lf)hf = np.trapz(abs(Y[(frq>=0.16) & (frq<=0.5)])) #Do the same for 0.16-0.5Hz (HF)
print("HF:", hf)同上,变了范围

这些是感兴趣频谱处频谱下的区域。请记住,从理论上讲,HF与呼吸有关,而LF与短期血压调节有关。这些措施也与增加精神活动有关。

全面包装
      我们已经走了很长一段路,现在可以从心率信号中提取许多有意义的指标。但是,如果您输入其他心率数据,则该模块很可能会失败,因为它可能比我们的理想数据更嘈杂,或者可能包含伪像。本系列的第三部分将处理信号过滤,错误检测和离群值剔除。

翻译—使用Python分析离散心率信号–第2部分相关推荐

  1. 翻译—使用Python分析离散心率信号–第1部分

    此文为翻译+自己的理解,github地址:https://github.com/paulvangentcom/heartrate_analysis_python 第1部分:打开数据,检测第一个峰并计算 ...

  2. Python分析离散心率信号(下)

    Python分析离散心率信号(下) 如何使用动态阈值,信号过滤和离群值检测来改善峰值检测. 一些理论和背景 到目前为止,一直在研究如何分析心率信号并从中提取最广泛使用的时域和频域度量.但是,使用的信号 ...

  3. Python分析离散心率信号(中)

    Python分析离散心率信号(中) 一些理论和背景 心率信号不仅包含有关心脏的信息,还包含有关呼吸,短期血压调节,体温调节和荷尔蒙血压调节(长期)的信息.也(尽管不总是始终如一)与精神努力相关联,这并 ...

  4. Python分析离散心率信号(上)

    Python分析离散心率信号(上) 一些理论和背景 心率包含许多有关信息.如果拥有心率传感器和一些数据,那么当然可以购买分析包或尝试一些可用的开源产品,但是并非所有产品都可以满足需求.也是这种情况.那 ...

  5. 离散度计算公式 python_Python分析离散心率信号(中)

    一些理论和背景 心率信号不仅包含有关心脏的信息,还包含有关呼吸,短期血压调节,体温调节和荷尔蒙血压调节(长期)的信息.也(尽管不总是始终如一)与精神努力相关联,这并不奇怪,因为大脑是一个非常饥饿的器官 ...

  6. matlab计算信号得频谱,用MATLAB分析离散信号的频谱与信号的采样

    <用MATLAB分析离散信号的频谱与信号的采样>由会员分享,可在线阅读,更多相关<用MATLAB分析离散信号的频谱与信号的采样(7页珍藏版)>请在人人文库网上搜索. 1.实验六 ...

  7. python 处理锯齿波信号

    python 处理锯齿波信号 预期学习目标(ILO): 您应该 了解傅里叶分析在时域中周期性信号的基础,即如何将周期性时域信号分解为基频. 能够从头编程周期波形,并将其与"scipy&quo ...

  8. 离散周期信号的傅里叶变换

    离散周期信号的傅里叶级数(DFS) 连续周期信号的傅里叶变换(CFT) 与连续时间情况一样,利用把一个周期信号的变换表示成频域中的冲激串的办法,就可以把离散时间周期信号也归并到离散时间傅里叶变换的范畴 ...

  9. python大数据分析实例-如何用Python分析大数据(以Twitter数据挖掘为例)

    原标题:如何用Python分析大数据(以Twitter数据挖掘为例) 来源:艾翻译(http://www.itran.cc/) 原文标题:Twitter Data Mining: A Guide to ...

最新文章

  1. Analysis and Design Overview
  2. Eclipse配置自动提示(eclipse设置代码API自动出现)
  3. 使用SWAGGER和ASP.NET CORE设置可选路由参数
  4. ChemBioDraw 制作DMT屏保
  5. 小程序·云开发的HTTP API调用丨实战
  6. maven 引入外部jar包的几种方式
  7. Save the Room【找规律】
  8. 实用的 Python 包 —— 使用 win32 的剪贴板
  9. 博士论文答辩||基于深度强化学习的复杂作业车间调度问题研究
  10. HTTP的概念以及请求消息的数据格式
  11. Java算法常见面试题及答案
  12. PL/SQL Developer用户登录ORA-01045 user lacks CREATE SESSION privilege logon denied
  13. 点击按钮弹出单选列表对话框和加载Webview
  14. 【抽象代数概念速查】Lagrange Interpolation-拉格朗日插值
  15. vue项目引入字体.ttf
  16. 关于OLED花屏的解决方案之一
  17. 科普计算机软硬件知识,科普显卡基础知识 让你更加了解显卡
  18. 百度网盘直接下载文件方法
  19. 快速将argparse的参数倒入到类中的__dict__
  20. Python制作智能桌宠2

热门文章

  1. 旅游评论情感分析(2)---前期调查总结
  2. 供应链服务平台方案:助供应链服务公司实现商品+决策+物流+售后协同办公
  3. 极客日报:腾讯宣布捐赠1亿元驰援河南;苹果回应iPhone 安全隐患;贝索斯完成10分钟太空之旅
  4. jquerymobile-16 select menu
  5. 网红奶茶品牌茶颜悦色,开业仅半小时就停业,黄牛价200元一杯
  6. 缺少msvc140.dll解决办法,缺少任意dll文件的解决办法
  7. CVPR2021/邻域自适应/图像翻译-DRANet: Disentangling Representation and Adaptation Networks
  8. 网络空间安全未来就业前景和就业方向,看着六点
  9. 业界大佬揭秘美颜技术的算法原理
  10. 蓝牙耳机音质变差或许该注意这些问题,学生党什么牌子蓝牙耳机性价比高?