Python 讀取HDF5檔案

何為xl發表於2020-11-15

參考部落格與網站:

https://baike.baidu.com/item/hdf%E6%96%87%E4%BB%B6/2590190

http://www.voidcn.com/article/p-aplswowh-bmq.html

https://www.cnblogs.com/dylancao/p/9756850.html

h5檔案介紹

h5檔案格式,HDF 的版本 5(HDF 版本 5不與 HDF 版本 4 及早期版本相容).HDF是什麼呢?就是Hierarchical Data Format,可以儲存不同型別的影像和數碼資料的檔案格式,並且可以在不同型別的機器上傳輸,同時還有統一處理這種檔案格式的函式庫。大多數普通計算機都支援這種檔案格式。
美國國家高階計算應用中心(National Center for Supercomputing Application,NCSA)為了滿足各種領域研究需求而研製的一種能高效儲存和分發科學資料的新型資料格式 。HDF可以表示出科學資料儲存和分佈的許多必要條件。

HDF的優點

HDF的優點有:
  自述性:對於一個HDF檔案裡的每一個資料物件,有關於該資料的綜合資訊(後設資料)。在沒有任何外部資訊的情況下,HDF允許應用程式解釋HDF檔案的結構和內容。
  通用性:許多資料型別都可以被嵌入在一個HDF檔案裡。例如,通過使用合適的HDF資料結構,符號、數字和圖形資料可以同時儲存在一個HDF檔案裡。
  靈活性:HDF允許使用者把相關的資料物件組合在一起,放到一個分層結構中,向資料物件新增描述和標籤。它還允許使用者把科學資料放到多個HDF檔案裡。
  擴充套件性:HDF極易容納將來新增加的資料模式,容易與其他標準格式相容。
  跨平臺性:HDF是一個與平臺無關的檔案格式。HDF檔案無需任何轉換就可以在不同平臺上使用。

HDF資料型別

HDF有6種主要資料型別:

柵格圖象,調色盤,科學資料庫,註釋,Vdata和Vgroup。

· 柵格圖象: 資料模式提供一種靈活方式儲存、描述柵格圖象資料,包括8bit柵格圖象。
· 調色盤: 也叫作彩色查對錶,它提供影像的色譜。
· 科學資料集: 用來儲存和描述多維科學資料陳列。
· Vdata: 是一個框架,用於儲存和描述資料表。
· HDF註釋: 是文字串,用來描述HDF檔案或HDF資料目標。
· Vgroup: 是用來把相關資料目標聯絡起來。一個Vgroup可以含有其它Vgroup,以及資料目標。任一個HDF目標均可以包括進某個Vgroup中。

HDF的檔案格式

HDF格式可以被看成一本帶目錄的多章節書。HDF檔案作為“資料書”,每一章包含不同型別的資料元素。HDF檔案用“資料目錄”列出資料元素。
一個HDF 檔案應包括一個檔案頭,一個或多個描述符塊,若干個資料元素。
資料頭是用來確定一個檔案是否為HDF檔案,描述符塊存有資料描述符的序號。一個資料描述符和資料元素一起組成了資料物件。資料物件是HDF 的基本結構。

檔案頭:

檔案頭佔用檔案的前4個位元組,它由4個ASCII碼形式的控制字元組成,每個字元佔用一個位元組。第一個控制字元是‘N’,第二個是‘C’, 第三個是‘S’,第四為‘A’,即(NCSA).

資料物件:

一個資料物件是由一個資料描述符和一個資料元素組成。資料描述符包含了資料元素的型別、位置、尺度等資訊。資料元素是實際的資料資料。HDF 這種資料組織方式可以實現HDF 資料的自我描述。
(1) 資料描述符
所有的資料描述符都為12個位元組長,它包含4個區域:識別符號(佔16-bit),參照數(16-bit),資料偏移量(32-bit),資料長度(32-bit)。
識別符號:
資料識別符號(tag)是用來確定資料元素區資料型別的。它是16位無符號整型值(1~65535),如果沒有與其相對應的資料元素,則tag為DFTGA_NULL(或0)。下面為tag的值的說明:
1~32767——HDF 結構專用
32768~64999——可由使用者定義
65000~65535——HDF 規格擴充套件使用
參照數:
對於HDF 檔案中的每個標記符,都有唯一的一個參照數與其相對應。參照數是一個16—bit無符號整型數,在資料物件中一般是不可變的。標記符和參照數相結合確定唯一的資料物件。
資料偏移量和長度:
資料偏移量是指從檔案開始位置到資料元素的起始位置所包含的位元組數。長度是指整個資料元素區佔用位元組數。資料偏移量和長度均為32-bit 無符號整型數。
(2) 資料元素
資料元素是資料物件中的裸資料部分。
(3) 在HDF 檔案中將資料物件分組
在HDF 檔案中通常將含有相關資料的資料物件分為一組。這些資料物件組稱為資料集。HDF 使用者採用應用介面來處理這些資料集。例如:一套8-bit的影像資料集一般有3個資料物件:一組物件用來描述資料集的成員,一組物件是影像資料,另一組物件則用來描述影像的尺度大小。一個資料物件可以同時屬於多個資料集,例如包含在一個柵格影像中的調色盤物件,如果它的標識號和參照值也同時包含在另一個資料集描述符中,那麼則可以被另一個柵格影像呼叫。

使用hdf5依賴於Python的工具包:h5py

h5接受的資料是矩陣跟mat方法一致,但是具有更強的壓縮效能
使用hdf5依賴於Python的工具包:h5py

# -*- coding: utf-8 -*-

import h5py
import numpy as np

#HDF5的寫入:
imgData = np.zeros((2,4))
f = h5py.File('HDF5_FILE.h5','w')   #建立一個h5檔案,檔案指標是f
f['data'] = imgData                 #將資料寫入檔案的主鍵data下面
f['labels'] = np.array([1,2,3,4,5])            #將資料寫入檔案的主鍵labels下面
f.close()                           #關閉檔案

#HDF5的讀取:
f = h5py.File('HDF5_FILE.h5','r')   #開啟h5檔案
# 可以檢視所有的主鍵
for key in f.keys():
    print(f[key].name)
    print(f[key].shape)
    print(f[key].value)

輸出結果:

(2, 4)
[[ 0. 0. 0. 0.]
[ 0. 0. 0. 0.]]
/labels
(5,)
[1 2 3 4 5]
Process finished with exit code 0
import h5py  #匯入工具包
import numpy as np
#HDF5的寫入:
imgData = np.zeros((30,3,128,256))
f = h5py.File('HDF5_FILE.h5','w')   #建立一個h5檔案,檔案指標是f
f['data'] = imgData                 #將資料寫入檔案的主鍵data下面
f['labels'] = range(100)            #將資料寫入檔案的主鍵labels下面
f.close()                           #關閉檔案
 
#HDF5的讀取:
f = h5py.File('HDF5_FILE.h5','r')   #開啟h5檔案
f.keys()                            #可以檢視所有的主鍵
a = f['data'][:]                    #取出主鍵為data的所有的鍵值
f.close()

使用pandas讀取

https://www.jb51.net/article/153643.htm

對h5py包理解不太深刻的話使用 pandas庫。

hdf5在儲存的是支援壓縮,使用的方式是blosc,這個是速度最快的也是pandas預設支援的。 使用壓縮可以提磁碟利用率,節省空間。 開啟壓縮也沒有什麼劣勢,只會慢一點點。 壓縮在小資料量的時候優勢不明顯,資料量大了才有優勢。 同時發現hdf讀取檔案的時候只能是一次寫,寫的時候可以append,可以put,但是寫完成了之後關閉檔案,就不能再寫了, 會覆蓋。

另外,為什麼單獨說pandas,主要因為本人目前對於h5py這個包的理解不是很深入,不知道如果使用該包存pd.DataFrame格式的檔案,不像numpy格式檔案可以直接儲存,因此本人只能依賴pandas自帶一些函式進行處理。

2、寫入檔案

使用函式:pd.HDFStore

import numpy as np
import pandas as pd
####生成9000,0000條資料,9千萬條
a = np.random.standard_normal((90000000,4))
b = pd.DataFrame(a)
####普通格式儲存:
h5 = pd.HDFStore('/data/stock/test_s.h5','w')
h5['data'] = b
h5.close()

####壓縮格式儲存
h5 = pd.HDFStore('/data/stock/test_c4.h5','w', complevel=4, complib='blosc')
h5['data'] = b
h5.close()

3、讀取檔案

使用函式:pd.read_hdf

引數:檔名,key

data=pd.read_hdf('/data/stock/test_c4.h5',key='data')

相關文章