Python处理HDF5文件:h5py库

h5py官方文档


简介

  HDF(Hierarchical Data Format)指一种为存储和处理大容量科学数据设计的文件格式及相应库文件。最早由美国国家超级计算应用中心 NCSA 研究开发,目前在非盈利组织HDF Group维护下继续发展。HDF支持多种商业及非商业的软件平台,包括MATLAB、Java、Python、R 和 Julia 等等,现在也提供了 Spark ,其版本包括了 HDF4 和 HDF5 。当前流行的版本是 HDF5。Python 中有一系列的工具可以操作和使用 HDF5 数据,其中最常用的是 h5py 和 PyTables。

  HDF5文件是一种存储dataset 和 group 两类数据对象的容器,其操作类似 python 标准的文件操作;File 实例对象本身就是一个组,以 / 为名,是遍历文件的入口。

  • dataset:数据集,可类比为 Numpy 数组,每个数据集都有一个名字(name)、形状(shape) 和类型(dtype),支持切片操作;
  • group:组,可以类比为 字典,它是一种像文件夹一样的容器;group 中可以存放 dataset 或者其他的 group,键就是组成员的名称,值就是组成员对象本身(组或者数据集)。

h5py库基本操作

安装h5py

conda install h5py

创建 h5py 文件

import h5py
# 方式一
f = h5py.File("myh5py1.h5", "w")
# 方式二
with h5py.File('myh5py2.h5', 'w') as f:

参数说明:

  • 第一个参数:文件名,可以是字节字符串或 unicode 字符串;
  • 第二个参数:mode
mode说明
r只读,文件必须存在
r+读 / 写,文件必须存在
w创建文件,已经存在的文件会被覆盖掉
w- / x创建文件,文件如果已经存在则出错
a打开已经存在的文件进行读 / 写,如果不存在则创建一个新文件读 / 写(默认)

创建dataset

函数:h5py.File.create_dataset(self, name, shape=None, dtype=None, data=None, **kwds)

方式一:创建一个空数据集并赋值

  • 创建空数据集时,只需指定数据集的 name 和 shape。dtype 默认为 np.float32,默认填充值为 0,亦可通过关键字参数 fillvalue 来改变。
f1 = h5py.File("myh5py1.h5", "w")
d = f1.create_dataset("dset1", (100,), 'i')
d[...] = np.arange(100)

方式二:直接创建一个数据集并赋值

  • 创建非空数据集时,只需指定 name 和具体的数据 data。shape 和 dtype 都会从 data 中自动获取,当然也可以显示的指定存储类型来节省空间。(单精度浮点比双精度浮点要节省一半的空间)
f2 = h5py.File("myh5py2.h5", "w")
# 1.
f2["dset2"] = np.arange(100)
# 2.
arr=np.arange(100)
dset=f2.create_dataset('dset2',data=arr)

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

深度学习之10分钟入门h5py

创建group

import h5py
import numpy as np

f = h5py.File("myh5py.h5", "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())

批量读、写HDF5文件

#-*- coding: utf-8 -*-
import h5py
import numpy as np
# 批量写入数据
def save_h5(h5f,data,target):
    shape_list=list(data.shape)
    if not h5f.__contains__(target):
        shape_list[0]=None
        dataset = h5f.create_dataset(target, data=data,maxshape=tuple(shape_list), chunks=True)
        return
    else:
        dataset = h5f[target]
    len_old=dataset.shape[0]
    len_new=len_old+data.shape[0]
    shape_list[0]=len_new
    dataset.resize(tuple(shape_list))
    dataset[len_old:len_new] = data
# 批量读取
def getDataFromH5py(fileName,target,start,length):
    with h5py.File(fileName,'r') as h5f:
        if not h5f.__contains__(target):
            res=[]
        elif(start+length>=h5f[target].shape[0]):
            res=h5f[target].value[start:h5f[target].shape[0]]
        else:
            res=h5f[target].value[start:start+length]
    return res
# 调用
file_name='./data.h5'
with h5py.File(file_name,'w') as h5f:
	features=np.arange(100)
	save_h5(h5f,data=np.array(features),target='mnist_features')
	save_h5(h5f,data=np.array(features),target='mnist_features')
	save_h5(h5f,data=np.array(features),target='mnist_features')
	save_h5(h5f,data=np.array(features),target='mnist_features')
	save_h5(h5f,data=np.array(features),target='mnist_features')
for i in range(10):
    d=getDataFromH5py('./data.h5','mnist_features',i*5,5)#每批读取5个数据
    print(d)

输出:

[0 1 2 3 4]
[5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]
[20 21 22 23 24]
[25 26 27 28 29]
[30 31 32 33 34]
[35 36 37 38 39]
[40 41 42 43 44]
[45 46 47 48 49]

特殊地,如果批量写入的数据为图像时:

# 按批次将图像数据及相应的标签数据写入一个h5py文件
IMAGE_DIMS = (80, 60, 3)# 图片维度
LABEL_DIMS=3 # 标签维度
img_total=40442# 图片总数目
img_batch=100# 每次存取的图片数目
img_num=img_total//img_batch+1# 需要读取的batch数
img_res=img_total-img_batch*(img_num-1)# 最后一个batch读取的图片数目

for img_i in range(img_num): #img_i 第几个batch
    if img_i == 0:
        h5f = h5py.File("./dataset/train_data.h5", "w") #build File object
        x = h5f.create_dataset("x_train", (img_batch,IMAGE_DIMS[0], IMAGE_DIMS[1],IMAGE_DIMS[2]), 
        maxshape=(None,IMAGE_DIMS[0], IMAGE_DIMS[1],IMAGE_DIMS[2]), 
        dtype =np.float32)# build x_train dataset
        y = h5f.create_dataset("y_train", (img_batch, LABEL_DIMS),maxshape=(None, LABEL_DIMS), 
        dtype =np.int32)# build y_train dataset
    else:
    	h5f = h5py.File("./dataset/train_data.h5", "a") # add mode
    	x = h5f["x_train"]
    	y = h5f["y_train"]
	
	ytem = label[img_i*img_batch:(img_i+1)*img_batch]
	image=[]
	for i in range(img_i*img_batch,(img_i+1)*img_batch):
		if i>=img_total:
			break
    	img = cv2.imread(path+str(i)+'.jpg') 
    	img=cv2.resize(img, (IMAGE_DIMS[1], IMAGE_DIMS[0]))
    	img=img_to_array(img)
    	image.append(img)
    image=np.array(image, dtype="float") / 255.0
    
    if img_i != img_num-1:
         x.resize([img_i*img_batch + img_batch,IMAGE_DIMS[0], IMAGE_DIMS[1],IMAGE_DIMS[2]])
         y.resize([img_i*img_batch + img_batch,LABEL_DIMS])

         x[img_i*img_batch:img_i*img_batch + img_batch] = image
         y[img_i*img_batch:img_i*img_batch + img_batch] = ytem #写入数据集 

         print('{} images are dealed with'.format(img_i))
    else:
         x.resize([img_i*img_batch+img_res,IMAGE_DIMS[0], IMAGE_DIMS[1],IMAGE_DIMS[2]])
         y.resize([img_i*img_batch+img_res,LABEL_DIMS])

         x[img_i*img_batch:img_i*img_batch + img_res] = image
         y[img_i*img_batch:img_i*img_batch + img_res] = ytem

         print('{} images are dealed with'.format(img_i))

h5f.close() #close file

深度学习入门笔记(十二):深度学习数据读取
h5py批量写入文件、读取文件,支持任意维度的数据
利用h5py 构建深度学习数据集

  • 18
    点赞
  • 89
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值