python处理ECG二进制文件(.dat文件)和.db文件

2023-11-11

python处理ECG二进制文件(.dat文件)和.db文件

最近拿到了一批ECG原数据文件(包括.dat和.db文件),需要自己解析,记录一下解析结果。

1、.dat 文件是病人的心电数据,以二进制形式读取和解析。

数据文件的说明:

数据文件记录的是8通道数据(I,II,V1,V2,V3,V4,V5,V6),读取后通过下列计算公式得出12通道的数据(I,II,III,aVR,aVF,aVL,V1,V2,V3,V4,V5,V6)。

# 8通道换算12导联计算公式
III = II - I
aVR = -(I+II)/2
aVL =  I - II/2
aVF = II - I/2

数据存储规则:数值采用 16 位有符号整型表示,数值范围-32768~32767,电极电压 1mV 对应数值 81.92。(这个解析方式只适合本数据,不同数据的存储规则可能不一样!)
数据的存储顺序:每一块包括8个导联,每一导联256个数据点(512个字节)。
在这里插入图片描述

# 需要用到的库
import numpy as np
import matplotlib.pyplot as plt
import os
import sqlite3
# .dat文件的读取
path = r'D:\data\yxd\2021\01\c85f6b13-b57a-4f7e-91ad-5b51906c4cef.dat'  # 路径
with open(file=path_dat, mode='rb') as f:
    data = f.read()
print(len(data))   
print(data[0:100])   # 查看前100个数据 

这里输出内容为字节,按照十六进制计算,两个字节为一个数据点。在这里插入图片描述

# 初始化要输出的字典,字典的键为导联名称,值为列表  保存导联对应的数值。
lead_name = ['I', 'II', 'V1', 'V2', 'V3', 'V4', 'V5', 'V6']
output = {}
for name in lead_name:
    output[name] = []

因为不确定是大端还是小端存取数据,所以两种存取方式都试了一下。这里也包括对补码的处理(如果符号位为1,将补码除符号位外所有位取反,加1 ,最后加上符号位为负)。

# 小端  表示先读取的低地址存储低位数据,后读取的高地址存储高位数据
index = 40960    #从data[40960]开始,因为前边一段时间的心电记录可能会不稳定或噪音比较多
for k in range(10):   # 读取数据块数,这里时间原因只读取10块
    for i in range(8):   # 导联数
        for j in range(256):  #每一导联的数据点数
            byte_high = bin(data[index])   #这里读取两个字节
            byte_low = bin(data[index+1])
            index+=2    #每读取两个字节,对data的索引加2
            data_plot = str(byte_low[3:]+byte_high[2:])   #两个字节以二进制拼接,并且要祛除符号位
            if byte_low[2] == '0':   # 符号位为正,直接按照原码读取
                value = int(data_plot, 2) * 0.0122    #二进制转化为十进制,并且按照规则将单位转化为mv
            elif byte_low[2] == '1':  #符号位为负,按照补码的规则转化为原码
                negative = ''    
                for m in range(len(data_plot)):  #对除符号位以外的取反
                    if data_plot[m] == '0':
                        negative += '1'
                    elif data_plot[m] == '1':
                        negative += '0'
                    else:
                        print("data_plot is not 0 or 1!")
                value = -1 * (int(negative, 2)+1) * 0.0122    
            else:
                print("data符号出错!")
#             print(value)
            output1[lead_name[i]].append(value)
print(len(output['I']))   #输出为2560  表示每导联正确读取了2560个数据点


# 大端   表示先读取的低地址存储高位数据,后读取的高地址存储低位数据
index = 40960    #从data[40960]开始,因为前边一段时间的心电记录可能会不稳定或噪音比较多
for k in range(10):   # 读取数据块数,这里时间原因只读取10块
    for i in range(8):   # 导联数
        for j in range(256):  #每一导联的数据点数
            byte_low = bin(data[index])   #这里读取两个字节
            byte_high = bin(data[index+1])
            index+=2    #每读取两个字节,对data的索引加2
            data_plot = str(byte_high[3:]+byte_low[2:])   #两个字节以二进制拼接,并且要祛除符号位
            if byte_high[2] == '0':   # 符号位为正,直接按照原码读取
                value = int(data_plot, 2) * 0.0122    #二进制转化为十进制,并且按照规则将单位转化为mv
            elif byte_high[2] == '1':  #符号位为负,按照补码的规则转化为原码
                negative = ''    
                for m in range(len(data_plot)):  #对除符号位以外的取反
                    if data_plot[m] == '0':
                        negative += '1'
                    elif data_plot[m] == '1':
                        negative += '0'
                    else:
                        print("data_plot is not 0 or 1!")
                value = -1 * (int(negative, 2)+1) * 0.0122    
            else:
                print("data符号出错!")
#             print(value)
            output1[lead_name[i]].append(value)
print(len(output['I']))   #输出为2560  表示每导联正确读取了2560个数据点![请添加图片描述](https://img-blog.csdnimg.cn/f3e40bd9e97c4638a48ec289ca73cd8b.png)

大端读取,描绘的波形明显是错误的请添加图片描述小端读取,描绘的ECG波形大致正确,所以确实是小端存取请添加图片描述

2、读取.db文件

path_ann = r'D:\data\yxd\2021\01\2cd05e3c-d599-4bb5-9905-a6faa00a1ece.db'  # 路径
mydb = sqlite3.connect(path_ann)  #连接数据库
cursor = mydb.cursor()  
cursor.execute("select * from HeartBeat")  # 执行SQL语句,查找HeartBeat表
col_name = [tuple[0] for tuple in cursor.description]     # 读取表HeartBeat的列名
print(col_name) 

在这里插入图片描述

# 将表内对应的列名设置为字典的键,列的值设置为字典的值。
annotation = {}
for name in col_name:
    annotation[name] = []
Tables = cursor.fetchall()
for item in Tables:
    for i in range(len(col_name)):
        annotation[col_name[i]].append(item[i])
# print(annotation.keys())

此时可以读取字典annotation中对应的字段。此时可以

以上全部代码写入.py文件如下

import numpy as np
import matplotlib.pyplot as plt
import os
import sqlite3


def load_data(path_dat):
    # 读取dat文件
    with open(file=path_dat, mode='rb') as f:
        data = f.read()
    block_num = int(os.path.getsize(path_dat)/512/8)
    lead_name = ['I', 'II', 'V1', 'V2', 'V3', 'V4', 'V5', 'V6']
    output = {}
    for name in lead_name:
        output[name] = []
    index = 0
    for k in range(block_num):
        for i in range(8):
            for j in range(256):
                byte_high = bin(data[index])
                byte_low = bin(data[index + 1])
                index += 2
                data_plot = str(byte_low[3:] + byte_high[2:])
                if byte_low[2] == '0':
                    value = int(data_plot, 2) * 0.0122
                elif byte_low[2] == '1':
                    negative = ''
                    for m in range(len(data_plot)):
                        if data_plot[m] == '0':
                            negative += '1'
                        elif data_plot[m] == '1':
                            negative += '0'
                        else:
                            print("data_plot is not 0 or 1!")
                    value = -1 * (int(negative, 2) + 1) * 0.0122
                else:
                    print("data符号出错!")
                #             print(value)
                output[lead_name[i]].append(value)
    for name_add in ['III', 'aVR', 'aVL', 'aVF']:
        output[name_add] = []
    for i in range(len(output['I'])):
        output['III'].append(output['II'][i] - output['I'][i])
        output['aVR'].append(output['II'][i] - output['I'][i] * 0.5)
        output['aVL'].append(output['I'][i] - output['II'][i] * 0.5)
        output['aVF'].append((output['II'][i] + output['I'][i]) * 0.5)
    return output


def load_ann(path_ann):
    mydb = sqlite3.connect(path_ann)
    cursor = mydb.cursor()
    cursor.execute("select * from HeartBeat")
    col_name = [tuple[0] for tuple in cursor.description] #列名
    # print(col_name)
    annotation = {}
    for name in col_name:
        annotation[name] = []
    Tables = cursor.fetchall()
    for item in Tables:
        for i in range(len(col_name)):
            annotation[col_name[i]].append(item[i])
    return annotation


if __name__ == '__main__':
    path_dat = r'D:\data\yxd\2021\01\c85f6b13-b57a-4f7e-91ad-5b51906c4cef.dat'
    path_ann = r'D:\data\yxd\2021\01\2cd05e3c-d599-4bb5-9905-a6faa00a1ece.db'
    data = load_data(path_dat)  # 返回一个字典
    ann = load_ann(path_ann)  # 返回一个字典
    print(data.keys())
    # plt.figure(figsize = (20,5))
    # plt.plot(data['I'][0:2500])
    # plt.figure(figsize = (20,5))
    # plt.plot(data['II'][0:2500])
    # plt.show()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python处理ECG二进制文件(.dat文件)和.db文件 的相关文章

  • 使用 python 进行串行数据记录

    Intro 我需要编写一个小程序来实时读取串行数据并将其写入文本文件 我在读取数据方面取得了一些进展 但尚未成功地将这些信息存储在新文件中 这是我的代码 from future import print function import se
  • Python逻辑运算符优先级[重复]

    这个问题在这里已经有答案了 哪个运算符优先4 gt 5 or 3 lt 4 and 9 gt 8 这会被评估为真还是假 我知道该声明3 gt 4 or 2 lt 3 and 9 gt 10 显然应该评估为 false 但我不太确定 pyth
  • 从 ffmpeg 获取实时输出以在进度条中使用(PyQt4,stdout)

    我已经查看了很多问题 但仍然无法完全弄清楚 我正在使用 PyQt 并且希望能够运行ffmpeg i file mp4 file avi并获取流式输出 以便我可以创建进度条 我看过这些问题 ffmpeg可以显示进度条吗 https stack
  • Django 模型在模板中不可迭代

    我试图迭代模型以获取列表中的第一个图像 但它给了我错误 即模型不可迭代 以下是我的模型和模板的代码 我只需要获取与单个产品相关的列表中的第一个图像 模型 py class Product models Model title models
  • Argparse nargs="+" 正在吃位置参数

    这是我的解析器配置的一小部分 parser add argument infile help The file to be imported type argparse FileType r default sys stdin parser
  • 如何在 pytest 中将单元测试和集成测试分开

    根据维基百科 https en wikipedia org wiki Unit testing Description和各种articles https techbeacon com devops 6 best practices inte
  • 如何计算numpy数组中元素的频率?

    我有一个 3 D numpy 数组 其中包含重复的元素 counterTraj shape 13530 1 1 例如 counterTraj 包含这样的元素 我只显示了几个元素 array 136 129 130 103 102 101 我
  • 为什么Python的curses中escape键有延迟?

    In the Python curses module I have observed that there is a roughly 1 second delay between pressing the esc key and getc
  • 切片 Dataframe 时出现 KeyError

    我的代码如下所示 d pd read csv Collector Output csv df pd DataFrame data d dfa df copy dfa dfa rename columns OBJECTID Object ID
  • 为什么在 Python 2.4 中使用 Unicode 数据会出现 ASCII 编码错误,而在 2.7 中却不会?

    我有一个程序 当在 Python 2 7 中运行时 会生成正确的 Unicode 输出到标准输出 当在 Python 2 4 中运行时 我得到UnicodeEncodeError ascii codec can t encode chara
  • python suds SOAP 请求中的名称空间前缀错误

    我使用 python suds 来实现客户端 并且在发送的 SOAP 标头中得到了错误的命名空间前缀 用于定义由element ref 在 wsdl 中 wsdl 正在引用数据类型 xsd 文件 请参见下文 问题出在函数上GetRecord
  • 将 JSON 对象传递给带有请求的 url

    所以 我想利用 Kenneth 的优秀请求模块 https github com kennethreitz requests 在尝试使用时偶然发现了这个问题自由库API http wiki freebase com wiki API 基本上
  • Pandas 根据 diff 列形成簇

    我正在尝试使用 Pandas 根据表示时间 以秒为单位 的列中的差异来消除数据框中的一些接近重复项 例如 import pandas as pd numpy as np df pd DataFrame 1200 1201 1233 1555
  • 创建嵌套字典单行

    您好 我有三个列表 我想使用一行创建一个三级嵌套字典 i e l1 a b l2 1 2 3 l3 d e 我想创建以下嵌套字典 nd a 1 d 0 e 0 2 d 0 e 0 3 d 0 e 0 b a 1 d 0 e 0 2 d 0
  • 使用 NumPy 将非均匀数据从文件读取到数组中

    假设我有一个如下所示的文本文件 33 346 1223 10 23 11 23 12 23 13 23 14 23 15 23 16 24 10 24 11 24 12 24 13 24 14 24 15 24 16 25 14 25 15
  • mac osx 10.8 上的初学者 python

    我正在学习编程 并且一直在使用 Ruby 和 ROR 但我觉得我更喜欢 Python 语言来学习编程 虽然我看到了 Ruby 和 Rails 的优点 但我觉得我需要一种更容易学习编程概念的语言 因此是 Python 但是 我似乎找不到适用于
  • 如何在 OSX 上安装 numpy 和 scipy?

    我是 Mac 新手 请耐心等待 我现在使用的是雪豹 10 6 4 我想安装numpy和scipy 所以我从他们的官方网站下载了python2 6 numpy和scipy dmg文件 但是 我在导入 numpy 时遇到问题 Library F
  • 默认情况下,Keras 自定义层参数是不可训练的吗?

    我在 Keras 中构建了一个简单的自定义层 并惊讶地发现参数默认情况下未设置为可训练 我可以通过显式设置可训练属性来使其工作 我无法通过查看文档或代码来解释为什么会这样 这是应该的样子还是我做错了什么导致默认情况下参数不可训练 代码 im
  • 限制 django 应用程序模型中的单个记录?

    我想使用模型来保存 django 应用程序的系统设置 因此 我想限制该模型 使其只能有一条记录 极限怎么办 尝试这个 class MyModel models Model onefield models CharField The fiel
  • Scrapy Spider不存储状态(持久状态)

    您好 有一个基本的蜘蛛 可以运行以获取给定域上的所有链接 我想确保它保持其状态 以便它可以从离开的位置恢复 我已按照给定的网址进行操作http doc scrapy org en latest topics jobs html http d

随机推荐

  • 经验积累①:关于设备程序的版本迭代方案详解

    关于设备程序的版本迭代方案详解 一 案例描述 对于嵌入式应用层来说 需要对设备的很多参数进行保存 为了使得这些配置参数掉电不丢失 因此在flash中生成配置文件用于保存设备参数 每当设备重启后 将参数读出 重发给设备 由于生成了可变的配置文
  • event_base_loop

    函数 int event base loop struct event base int 等待事件被触发 然后调用它们的回调函数 这是 event base dispatch的更灵活版本 默认情况下 这个循环会一直运行 直到没有添加的事件
  • 在macOS下安装和配置MySQL数据库

    一 到社区下载安装包 官网地址 MySQL MySQL Community Downloadshttps dev mysql com downloads MySQL Download MySQL Community Serverhttps
  • 身边的逻辑学——过度概括(1)

    过度概括 overgeneralization 概括与过度概括有何不同 概括知识是暂定的 因为它基于对经验的概括 原则上 下一个经验很可能出乎你的意料之外 使你 我们每个人 不得不对先前概括得出的结论感到怀疑 了解概括的本质有助于发现真理
  • C/C++ vs2017连接MySQL数据库 - 增删改查(详细步骤)

    在开发中 数据库是必不可少 这篇文章将介绍使用C C 如何进行连接MySQL数据库 并实现增删改查操作 注意 此篇文章所讲的是C C 如何操控MySQL进行简单的 常用的 增删改查 的操作 目录 一 配置Visual Studio 二 C
  • 不可不说的Java“锁”事

    前言 Java提供了种类丰富的锁 每种锁因其特性的不同 在适当的场景下能够展现出非常高的效率 本文旨在对锁相关源码 本文中的源码来自JDK 8 使用场景进行举例 为读者介绍主流锁的知识点 以及不同的锁的适用场景 Java中往往是按照是否含有
  • ACL访问控制列表原理及实例

    目录 一 ACL概述 1 ACL访问控制列表作用 2 ACL访问控制列表工作原理 3 ACL访问控制列表处理过程原则 二 ACL访问控制列表类型 1 标准访问控制列表 2 扩展访问控制列表 三 配置实例 1 要求 用标准访问控制列表 vla
  • qt modules public internal 私有头文件 private

    qt对源码进行了分层 把数据成员都单独拉到一个 p h的头文件中 形成internal部分的接口类Qt之二进制兼容 qt p h 文件的用途是什么 qt不建议用户使用internal部分的接口类 因为不同平台和不用版本的qt interna
  • sort函数的时间、空间复杂度

    sort函数进行排序的时间复杂度为n log2n 原理 不是简单的快排 STL的sort 算法 数据量大时采用Quick Sort 分段递归排序 一旦分段后的数据量小于某个门槛 为避免Quick Sort的递归调用带来过大的额外负荷 就改用
  • Grade for Android(从 Gradle 和 AS 开始)

    http www open open com lib view open1451536597026 html 正如大家所见 这是本英文书 而由于国内的gradle翻译资料不全 所以特次开辟专栏 翻译gradle for android这本书
  • 基于JWT的springboot权限验证技术实现

    JWT简介 Json Web Token JWT JSON网络令牌 是为了在网络应用环境间传递声明而制定的一种基于JSON的开放标准 RFC 7519 JWT是一个轻便的安全跨平台传输格式 定义了一个紧凑的自包含的方式用于通信双方之间以 J
  • 通过Navicat创建ER图技巧笔记

    1 通过已有数据库逆向创建模型时 切忌一次生成所有表ER图 建议先将所有表添加到模型 然后依次从上至下添加到图表 2 单张图表可以通过图表模式进行重命名 在左侧图表窗口最上方 右键当前图表 gt 重命名 gt 修改 3 单张图表不宜过大 4
  • 解决vscode jupyter启动kernel错误的方案Failed to connect to Jupyter notebook.

    最近在vscode里面运行 ipynb文件的时候经常性地会出现报错情况 报错的图片内容如下 Failed to connect to Jupyter notebook 经过网上一番查阅方法之后 终于将配件搭建好了 解决方法为输入如下命令 p
  • 【Unity 学习笔记】动画系统(续)和事件

    在上一篇笔记中 我们使用Unity的动画系统实现了移动和跳跃的动画 在这一篇笔记中我们将使用Unity事件的方式来实现受伤和死亡的动画 首先创建一个受伤动画 由于素材中没有现成的受伤动画 我们只能手动创建一个简陋的闪烁动画 主要现实在角色受
  • java变量的类别和作用范围

    1 类别及作用范围 类变量 在类中用static修饰的字段 存储位置 方法区 生命周期 随着JVM的消亡而消失 生命周期最长 局部变量 在方法中存在的 或者形参 存储位置 栈帧中 生命周期 随着方法的调用而存在 生命周期最短 实例变量 在类
  • GCC编译器-<嵌入式Linux应用程序开发标准教程>-华清远见

    3 3 gcc编译器 GNU CC 简称为gcc 是GNU项目中符合ANSI C标准的编译系统 能够编译用C C 和Object C等 语言编写的程序 gcc不仅功能强大 而且可以编译如C C Object C Java Fortran P
  • LA@特征值和特征向量的性质

    文章目录 方阵特征值和特征向量的性质 特征值之和 特征值之积 推论 特征值判定方阵的可逆性 证明 小结 导出性质 可逆矩阵的特征值性质 转置矩阵和特征值 矩阵多项式的特征值 不同特征值的特征向量线性无关定理 推论 推广 特征向量线性组合 特
  • [python爬虫] 爬取图片无法打开或已损坏的简单探讨

    本文主要针对python使用urlretrieve或urlopen下载百度 搜狗 googto 谷歌镜像 等图片时 出现 无法打开图片或已损坏 的问题 作者对它进行简单的探讨 同时 作者将进一步帮你巩固selenium自动化操作和urlli
  • 【C语言】数据结构-----字符串匹配之KMP算法

    目录 算法简介 匹配原理 第一次匹配 第二次匹配 第三次匹配 第四次匹配 可能失配位置 next数组求解 next数组的由来 next数组的用法 next数组代码的实现 KMP算法的实现 示例 完整的代码 KMP算法与BF算法相比较 算法简
  • python处理ECG二进制文件(.dat文件)和.db文件

    python处理ECG二进制文件 dat文件 和 db文件 最近拿到了一批ECG原数据文件 包括 dat和 db文件 需要自己解析 记录一下解析结果 1 dat 文件是病人的心电数据 以二进制形式读取和解析 数据文件的说明 数据文件记录的是