数据集文件格式
1. 简介2. HDF52.1 HDF5(.h5)文件结构2.2 API2.2.1 打开或创建h5py文件2.2.2 创建dataset数据集2.2.3 创建group组(类似于文件夹)2.2.4 混合模式
3. MAT3.1 MAT文件格式3.2 文件 头3.3 数据单元的格式3.4 Python接口
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 numberLittle-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']