数据集文件格式

1. 简介

文件格式扩展名
HDF5.h5H5文件是层次数据格式第5代的版本, 以key-value的方式组织数据的一个容器
mat.m或.matmat文件是Matlab的数据存储的标准格式(二进制或ASCII)

2. HDF5

  • HDF5定义

    • H5文件是层次数据格式第5代的版本(Hierarchical Data Format,HDF5)
    • 支持n维数据集,且数据集中的每个元素可以是一个复杂对象
    • key-value的方式组织数据的一个容器
  • 开发者

    • 它是由美国超级计算与应用中心研发的文件格式,用以存储和组织大规模数据
    • 目前由非营利组织HDF小组提供支持
  • 用途

    • 很多商业和非商业组织都支持这种文件格式,如Java,MATLAB,Python,R等
    • 在内存占用、压缩、访问速度方面都有非常优秀的特性,在工业领域和科学领域都有很多运用。
  • 特点
    在这里插入图片描述

    • 易于共享:是一个自描述的文件,所有数据和元数据均可保存在同一文件中
    • 跨平台+多语言(C, C++, Python,Java等)
    • 快速I/O:访问速度快、存储空间小
    • 大数据:对数据对象的数量和大小均没有限制
    • 在数据中包含元数据:流水型生命周期和管道

2.1 HDF5(.h5)文件结构

  • H5将文件结构简化成两个主要的对象类型
    • 数据集(dataset):就是同一类型数据的多维数组。
    • 组(group):是一种容器结构,可以包含数据集和其他组,类似于文件夹
  • H5文件是一种真正的层次结构、文件系统式的数据类型
  • 元数据:是由用户定义的,以命名属性的形式附加到组和数据集中。更复杂的存储形式如图像和表格可以使用数据集、组和属性来构建。
  • HDF5源码

2.2 API

2.2.1 打开或创建h5py文件

  • 函数定义
class File(name, mode=None, driver=None, libver=None, userblock_size=None, **kwds)
  • mode说明:
    • r: 只读,文件必须存在
    • r+:读写,文件必须存在
    • w:创建新文件写,已经存在的文件会被覆盖掉
    • w- / x:创建新文件写,文件如果已经存在则出错
    • a:打开已经存在的文件进行读写,如果不存在则创建一个新文件读写,此为默认的 mode

2.2.2 创建dataset数据集

create_dataset(self, name, shape=None, dtype=None, data=None, **kwds)
# name: 数据集的名字
# shape:以一个tuple或list的形式指明创建dataset的shape
  • 示例代码
import h5py
import numpy as np

# 创建一个新文件
f=h5py.File("myh5py-1.h5","w")

# 分别创建dset1,dset2,dset3这三个数据集
# dset1:有现成的numpy数组,可以在创建数据集的时候就赋值,不必指定数据的类型和形状了,只需要把数组名传给参数data。
a=np.arange(20)                              
d1=f.create_dataset("dset1",data=a)

# dset2: 是数据集的name,(3,4)代表数据集的shape,i代表的是数据集的元素类型
d2=f.create_dataset("dset2",(3,4),'i')   
d2[...]=np.arange(12).reshape((3,4))    #赋值

#直接按照下面的方式创建数据集并赋值
f["dset3"]=np.arange(15)

for key in f.keys():
    print(f[key].name)
    print(f[key].shape)
    print(f[key].value)

  • 输出
/dset1
(20,)
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19]

/dset2
(3, 4)
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
 
/dset3
(15,)
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14]

2.2.3 创建group组(类似于文件夹)

  • 函数定义
create_group(self, name, track_order=False)
  • 示例代码
import h5py
import numpy as np
f=h5py.File("myh5py-3.hdf5","w")

#创建一个名字为bar的组
g1=f.create_group("bar")

#在bar这个组里面分别创建name为dset1,dset2的数据集并赋值。
g1["dset1"]=np.arange(10)
g1["dset2"]=np.arange(12).reshape((3,4))

for key in f.keys():
    print(f[key].name)
    
print('==============')    

for key in g1.keys():
    print(g1[key].name)
    print(g1[key].shape)
    print(g1[key].value)
  • 输出
/bar
==============
/bar/dset1
(10,)
[0 1 2 3 4 5 6 7 8 9]
/bar/dset2
(3, 4)
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

2.2.4 混合模式

  • 示例代码
import h5py
import numpy as np
f=h5py.File("myh5py-2.hdf5","w")

#创建组bar1,组bar2,数据集dset
g1=f.create_group("bar1")
g2=f.create_group("bar2")
d=f.create_dataset("dset",data=np.arange(10))

#在bar1组里面创建一个组car1和一个数据集dset1。
c1=g1.create_group("car1")
d1=g1.create_dataset("dset1",data=np.arange(10))

#在bar2组里面创建一个组car2和一个数据集dset2
c2=g2.create_group("car2")
d2=g2.create_dataset("dset2",data=np.arange(10))

#根目录下的组和数据集
print(".............")
for key in f.keys():
    print(f[key].name)

#bar1这个组下面的组和数据集
print(".............")
for key in g1.keys():
    print(g1[key].name)


#bar2这个组下面的组和数据集
print(".............")
for key in g2.keys():
    print(g2[key].name)

#顺便看下car1组和car2组下面都有什么,估计你都猜到了为空。
print(".............")
print(c1.keys())
print(c2.keys())

  • 输出
.............
/bar1
/bar2
/dset
.............
/bar1/car1
/bar1/dset1
.............
/bar2/car2
/bar2/dset2
.............
<KeysViewHDF5 []>
<KeysViewHDF5 []>

3. MAT

  • mat数据格式是Matlab的数据存储的标准格式
  • mat文件是标准的二进制文件,还可以ASCII码形式保存和加载,在Matlab中打开显示类似于单行EXCEL表格
  • 在Matlab中主要使用load()函数导入一个mat文件,使用save()函数保存一个mat文件

3.1 MAT文件格式

  • 在matlab version 5中,MAT文件由一个128字节的文件头和若干个数据单元组成。每个数据单元有一个8个字节的tag,用于说明数据单元的占用的字节数(不包括tag的8个字节)和数据类型

3.2 文件 头

  • 文件头header里有124字节的文本描述区域和4个字节的flag
    • Header代码说明
     char mat_data_fhead1[51] = {"MATLAB 5.0 MAT-file, Platform: PCWIN, Created on: "};   
     char mat_data_fhead2[51] = {"                                                  "};    
     char mat_data_fhead3[4] = {0, 0x01, 0x49, 0x4d};   
     char* datetime = NULL;   
     time_t ltime;   
     tm* today;   
    
     time(ltime);   
     today = localtime(ltime);   
     datetime = asctime(today);   
   
     fwrite(mat_data_fhead1, 1, 50, fp);   
     fwrite(datetime, 1, 24, fp);   
     fwrite(mat_data_fhead2, 1, 50, fp);   
     fwrite(mat_data_fhead3, 1, 4, fp); # flag (4字节)
  • flag(4字节)
    • flag中的前2个字节说明version,后两个字节是endian indicator
    • 文本描述区域主要说明MAT文件的版本,创建于哪个平台,创建时间
    • flag中的version说明的是创建这个MAT文件的matlab的版本
    • edian indicator包括两个字符M和I
      • 关于edian:endian: The ordering of bytes in a multi-byte number
      • Little-Endian:就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端
      • Big-Endian:就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端
      • 网络字节序:TCP/IP各层协议将字节序定义为Big-Endian,因此TCP/IP协议中使用的字节序通常称之为网络字节序
      • 若edian indicator中的值为MI,则读取MAT数据时应该用IM的顺序。若对于16bit的数据,则要进行两个字节数据的交换。

3.3 数据单元的格式

  • 每个数据单元开头都有8个字节的tag用于说明数据单元存储的数据类型(datatype)字节数(不包括tag的8个字节)
  • 接下来的就是存储的数据。数据需要64bit对齐,不够时要补齐到64bit。数据类型是miMATRIX时,数据单元tag中字节数包括矩阵中每个padding的数据个数
  • datatype值为14的数据类型是:array data,包括了各种类型的array,如数值矩阵,字符矩阵,稀疏矩阵

3.4 Python接口

  • 在python中可以使用scipy.io中的函数读写mat文件:
    • loadmat():读取mat文件
    • savemat():保存mat文件
  • 写入和读取的数据都是字典格式
  • 示例代码
import scipy.io as scio

# write mat file
dataFile = "test.m"
data = {}
data['A'] = 'I am A' 
data['B'] = 'I am B'

#scio.savemat(dataFile, {'A':data['A'], 'B':data['B']})
scio.savemat(dataFile, data)

# read mat file
data_r = scio.loadmat(dataFile)
print(data_r)
print(type(data_r))
for key in data_r.keys():
    print(key,':', data_r[key])
  • 输出
{'__header__': b'MATLAB 5.0 MAT-file Platform: nt, Created on: Thu Oct 22 09:58:25 2020', '__version__': '1.0', '__globals__': [], 'A': array(['I am A'], dtype='<U6'), 'B': array(['I am B'], dtype='<U6')}
<class 'dict'>
__header__ : b'MATLAB 5.0 MAT-file Platform: nt, Created on: Thu Oct 22 09:58:25 2020'
__version__ : 1.0
__globals__ : []
A : ['I am A']
B : ['I am B']
  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值