【Kaggle竞赛】h5py库快速入门

2022-09-05 13:45:13 浏览数 (1)

Contents

  • 1 一,核心知识(Core concepts)
  • 2 二,附录,创建一个HDF5文件(Appendix: Creating a file)
  • 3 三,组和分层组织(Groups and hierarchical organization)
  • 4 四,属性(Attributes)
  • 5 五,参考资料

本文翻译自h5py官网,为了更适合国人阅读,内容有所整理和改动。记住不要重复写入HDF5文件,否则会报错。

一,核心知识(Core concepts)

h5py文件是存放两类对象的容器,数据集(dataset)和组(group)。

  • dataset类似数组的数据集合,和numpy的数组差不多。
  • group是类似文件夹一样的容器,可以包含dataset和其他groups,它也好比python中的字典,有键(key)和值(value)。

使用h5py要记住的最基本的事情就是:

Groups就像字典(dictionaries)一样工作,而datasets像Numpy数组(arrays)一样工作!

假设有人给你发送了一个HDF5文件,mmytestfile.hdf5。(如果想要自己创建HDF5文件,可阅读下文的附录:创建一个HDF5文件)。对于学习使用HDF5文件,我们要做的第一件事当然是打开文件进行阅读了。示例代码如下:

代码语言:javascript复制
import h5py
f = h5py.File('mytestfile.hdf5','r')

h5py文件对象(File object)的学习是我们开始的起点。那么在这个文件对象中储存了什么呢?要记住上文所说的,,h5py.File就像一个字典,因此我们可以检查keys(键)。示例代码如下:

代码语言:javascript复制
list(f.keys())

[‘mydataset’]

我们观察之后可以发现,h5py.File创建的文件对象(File object)里面只有一个数据集(dataset),名字是’mydataset’,我们来检查一下这个 Dataset 对象。

代码语言:javascript复制
dset = f['mydataset']

我们获得的对象不是数组,而是一个HDF5 dataset。和Nupy数组一样,dataset也有shape和data type属性,代码示例如下:

代码语言:javascript复制
dset.shape
dset.dtype

(100,) dtype(‘int32’)

dataset同样也支持数组形式的切片(slicing)操作。读写HDF5 dataset的代码示例如下:

代码语言:javascript复制
dset[...] = np.arange(100)
dset[0]
dset[10]
dset[0:100:10]

0 10 array([ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90])

更多内容,请学习File Objects和Datasets。

总的运行示例程序,,截图如下:

二,附录,创建一个HDF5文件(Appendix: Creating a file)

读到这里,你可能会想知道mytestdata.hdf5这个文件是怎么被创建的。我们可以通过设定mode(文件模式)为w来对文件进行初始化。其他初始化模式如下:

r

读模式,前提是文件已经存在

r

可读可写模式,文件必须存在

w

创建文件,如果文件存在则截断(truncate)

w- or x

创建文件,如果文件已经存在则创建失败

a

如果文件存在则进入可读可写模型,文件不存在则创建

dset = f.create_dataset(“mydataset”,(100,),dtype=’i’)

File object其实也是一个上下文管理器,所以下面的代码能够正常工作:

代码语言:javascript复制
import numpy as np
import h5py
with h5py.File("mytestfile2.hdf5","w") as f:
    dset = f.create_dataset("mydataset1",(100,),dtype='i')

三,组和分层组织(Groups and hierarchical organization)

“HDF”代表“分层数据格式”(“Hierarchical Data Format”)。HDF5文件中的每个对象都有一个名字,并且它们以 POSIX 方式分层,用一个反斜杠 / 分隔开:

代码语言:javascript复制
dset.name

‘/mydataset’

在这个系统中,”folders”被称为组(groups)。我们创建的File object本身也是一个group,下面代码的这种情况是根组(root group,也可以称为起始组或起始文件夹,意味着最顶层的文件夹),命名为一个反斜杠符号,/:

代码语言:javascript复制
f.name

u’/’

创建子组(subgroup)是通过create_group方法实现的。但是我们先得以模式为”a”的方式打开File object。代码示例如下:

代码语言:javascript复制
f = h5py.File("mydataset.hdf5","a")
grp = f.create_group("subgroup")

所有的Group对象都有create_*方法,就像File object一样,代码示例如下:

代码语言:javascript复制
dset2 = grp.create_dataset("another_dataset",(50,),dtype='f')
dset2.name

‘/subgroup/another_dataset’

顺便说下,我们没必要一个个手动创建所有中间组,指定好完整路径就可以正常工作了,代码示例如下:

代码语言:javascript复制
dset3 = f.create_dataset('subgroup2/dataset_three',(10,),dtype='i')
dset3.name

‘/subgroup2/dataset_three’

Groups支持大多数Python字典(dictionary)风格的操作。你可以通过使用键名来检索文件中的对象

代码语言:javascript复制
dataset_three = f['subgroup2/dataset_three']

也可以迭代的方式遍历一个组内的所有成员:

代码语言:javascript复制
for name in f:
    print(name)

mydataset subgroup subgroup2

成员资格测试也使用名称:(检查Group成员是否在Group中)

代码语言:javascript复制
"mydataset" in f

True

代码语言:javascript复制
"somethingelse" in f

False

也可以使用完整的路径名称来检查:

代码语言:javascript复制
"subgroup/another_dataset" in f

True

当然,也有一些我们比较熟悉的方法,如 keys(),values(),items(),iter() 以及 get() 方法等。这些方法其实就是Python字典常用的方法。

由于遍历组(Group)只会产生其直接关联的成员,迭代一个完整的组(Group)对象可以使用 visit() 和 visititems() 方法,下面的代码示例使用了 visit 方法:

代码语言:javascript复制
def printname(name):
    print(name)
f.visit(printname)

mydataset subgroup subgroup/another_dataset subgroup2 subgroup2/dataset_three

更多内容,请参考Groups。

四,属性(Attributes)

HDF5最大特性之一就是可以存储元数据在其描述的数据旁边。所有groups和datasets都都支持称为属性的附加命名数据位。(这段话好难翻译啊,建议参考原文)。

One of the best features of HDF5 is that you can store metadata right next to the data it describes. All groups and datasets support attached named bits of data called attributes.

Attributes是通过attrs代理对象访问的,它可以通过像字典(dictionary)类似的接口来实现:

代码语言:javascript复制
>> dset.attrs['temperature'] = 99.5
>>> dset.attrs['temperature']
99.5
>>> 'temperature' in dset.attrs
True

更多内容,请参考Attributes.

五,参考资料

  • http://docs.h5py.org/en/latest/quick.html

0 人点赞