Python 存儲與讀取HDF5文件


 

 

HDF5 簡介

HDF(Hierarchical Data Format)指一種為存儲和處理大容量科學數據設計的文件格式及相應庫文件。HDF 最早由美國國家超級計算應用中心 NCSA 開發,目前在非盈利組織 HDF 小組維護下繼續發展。當前流行的版本是 HDF5。HDF5 擁有一系列的優異特性,使其特別適合進行大量科學數據的存儲和操作,如它支持非常多的數據類型,靈活,通用,跨平台,可擴展,高效的 I/O 性能,支持幾乎無限量(高達 EB)的單文件存儲等,詳見其官方介紹:https://support.hdfgroup.org/HDF5/

HDF5 結構

HDF5 文件一般以 .h5 或者 .hdf5 作為后綴名,需要專門的軟件才能打開預覽文件的內容。HDF5 文件結構中有 2 primary objects: Groups 和 Datasets。

  • Groups 就類似於文件夾,每個 HDF5 文件其實就是根目錄 (root) group'/',可以看成目錄的容器,其中可以包含一個或多個 dataset 及其它的 group
  • Datasets 類似於 NumPy 中的數組 array,可以當作數組的數據集合 。

每個 dataset 可以分成兩部分: 原始數據 (raw) data values 和 元數據 metadata (a set of data that describes and gives information about other data => raw data)。

+-- Dataset | +-- (Raw) Data Values (eg: a 4 x 5 x 6 matrix) | +-- Metadata | | +-- Dataspace (eg: Rank = 3, Dimensions = {4, 5, 6}) | | +-- Datatype (eg: Integer) | | +-- Properties (eg: Chuncked, Compressed) | | +-- Attributes (eg: attr1 = 32.4, attr2 = "hello", ...) | 

從上面的結構中可以看出:

  • Dataspace 給出原始數據的秩 (Rank) 和維度 (dimension)
  • Datatype 給出數據類型
  • Properties 說明該 dataset 的分塊儲存以及壓縮情況
    • Chunked: Better access time for subsets; extendible
    • Chunked & Compressed: Improves storage efficiency, transmission speed
  • Attributes 為該 dataset 的其他自定義屬性

整個 HDF5 文件的結構如下所示:

+-- /
|   +-- group_1
|   |   +-- dataset_1_1
|   |   |   +-- attribute_1_1_1
|   |   |   +-- attribute_1_1_2
|   |   |   +-- ...
|   |   |
|   |   +-- dataset_1_2
|   |   |   +-- attribute_1_2_1
|   |   |   +-- attribute_1_2_2
|   |   |   +-- ...
|   |   |
|   |   +-- ...
|   |
|   +-- group_2
|   |   +-- dataset_2_1
|   |   |   +-- attribute_2_1_1
|   |   |   +-- attribute_2_1_2
|   |   |   +-- ...
|   |   |
|   |   +-- dataset_2_2
|   |   |   +-- attribute_2_2_1
|   |   |   +-- attribute_2_2_2
|   |   |   +-- ...
|   |   |
|   |   +-- ...
|   |
|   +-- ...
|
一個 HDF5 文件從一個命名為 "/" 的 group 開始,所有的 dataset 和其它 group 都包含在此 group 下,當操作 HDF5 文件時,如果沒有顯式指定 group 的 dataset 都是默認指 "/" 下的 dataset,另外類似相對文件路徑的 group 名字都是相對於 "/" 的。
安裝
pip install h5py

Python讀寫HDF5文件

#!/usr/bin/python
# -*- coding: UTF-8 -*-
#
# Created by WW on Jan. 26, 2020
# All rights reserved.
#

import h5py
import numpy as np

def main():
    #===========================================================================
    # Create a HDF5 file.
    f = h5py.File("h5py_example.hdf5", "w")    # mode = {'w', 'r', 'a'}

    # Create two groups under root '/'.
    g1 = f.create_group("bar1")
    g2 = f.create_group("bar2")

    # Create a dataset under root '/'.
    d = f.create_dataset("dset", data=np.arange(16).reshape([4, 4]))

    # Add two attributes to dataset 'dset'
    d.attrs["myAttr1"] = [100, 200]
    d.attrs["myAttr2"] = "Hello, world!"

    # Create a group and a dataset under group "bar1".
    c1 = g1.create_group("car1")
    d1 = g1.create_dataset("dset1", data=np.arange(10))

    # Create a group and a dataset under group "bar2".
    c2 = g2.create_group("car2")
    d2 = g2.create_dataset("dset2", data=np.arange(10))

    # Save and exit the file.
    f.close()

    ''' h5py_example.hdf5 file structure
    +-- '/'
    |   +--    group "bar1"
    |   |   +-- group "car1"
    |   |   |   +-- None
    |   |   |   
    |   |   +-- dataset "dset1"
    |   |
    |   +-- group "bar2"
    |   |   +-- group "car2"
    |   |   |   +-- None
    |   |   |
    |   |   +-- dataset "dset2"
    |   |   
    |   +-- dataset "dset"
    |   |   +-- attribute "myAttr1"
    |   |   +-- attribute "myAttr2"
    |   |   
    |   
    '''

    #===========================================================================
    # Read HDF5 file.
    f = h5py.File("h5py_example.hdf5", "r")    # mode = {'w', 'r', 'a'}

    # Print the keys of groups and datasets under '/'.
    print(f.filename, ":")
    print([key for key in f.keys()], "\n")  

    #===================================================
    # Read dataset 'dset' under '/'.
    d = f["dset"]

    # Print the data of 'dset'.
    print(d.name, ":")
    print(d[:])

    # Print the attributes of dataset 'dset'.
    for key in d.attrs.keys():
        print(key, ":", d.attrs[key])

    print()

    #===================================================
    # Read group 'bar1'.
    g = f["bar1"]

    # Print the keys of groups and datasets under group 'bar1'.
    print([key for key in g.keys()])

    # Three methods to print the data of 'dset1'.
    print(f["/bar1/dset1"][:])        # 1. absolute path

    print(f["bar1"]["dset1"][:])    # 2. relative path: file[][]

    print(g['dset1'][:])        # 3. relative path: group[]



    # Delete a database.
    # Notice: the mode should be 'a' when you read a file.
    '''
    del g["dset1"]
    '''

    # Save and exit the file
    f.close()

if __name__ == "__main__":
    main()

相關代碼示例

創建一個h5py文件

import h5py
f=h5py.File("myh5py.hdf5","w")

創建dataset

import h5py
f=h5py.File("myh5py.hdf5","w")
#deset1是數據集的name,(20,)代表數據集的shape,i代表的是數據集的元素類型
d1=f.create_dataset("dset1", (20,), 'i')
for key in f.keys():
    print(key)
    print(f[key].name)
    print(f[key].shape)
    print(f[key].value)

輸出:
dset1
/dset1
(20,)
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]

賦值

import h5py
import numpy as np
f=h5py.File("myh5py.hdf5","w")

d1=f.create_dataset("dset1",(20,),'i')
#賦值
d1[...]=np.arange(20)
#或者我們可以直接按照下面的方式創建數據集並賦值
f["dset2"]=np.arange(15)

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

輸出:
/dset1
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19]
/dset2
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14]

創建group

import h5py
import numpy as np
f=h5py.File("myh5py.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 g1.keys():
    print(g1[key].name)
    print(g1[key].value)

輸出:
/bar/dset1
[0 1 2 3 4 5 6 7 8 9]
/bar/dset2
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]

刪除某個key下的數據

# 刪除某個key,調用remove
f.remove("bar")

最后pandsa讀取HDF5格式文件

 
import pandas as pd
import numpy as np

# 將mode改成r即可
hdf5 = pd.HDFStore("hello.h5", mode="r")
# 或者
"""
hdfs = pd.read_hdf("hello.h5", key="xxx")
"""

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM