最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python操作處理?HDF5?文件的詳細(xì)操作

 更新時(shí)間:2026年06月25日 10:03:53   作者:Achuan-2  
在Python中,h5py?是最主流的?HDF5?操作庫,它提供了類似?Python?字典(Dict)和?NumPy?數(shù)組(ndarray)的高級(jí)接口,能夠無縫地與科學(xué)計(jì)算生態(tài)集成,本文介紹Python操作處理HDF5文件的詳細(xì)操作,感興趣的朋友一起看看吧

鏈接:https://www.zhihu.com/question/581283129/answer/2051633173038159258
來源:知乎
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。

可以使用h5py包

HDF5(Hierarchical Data Format version 5)是一種設(shè)計(jì)用于存儲(chǔ)和管理大規(guī)模、復(fù)雜數(shù)據(jù)的高性能文件格式。在 Python 中,h5py? 是最主流的 HDF5 操作庫,它提供了類似 Python 字典(Dict)和 NumPy 數(shù)組(ndarray)的高級(jí)接口,能夠無縫地與科學(xué)計(jì)算生態(tài)集成。

HDF5 核心概念

HDF5 文件的內(nèi)部結(jié)構(gòu)非常類似于操作系統(tǒng)中的文件系統(tǒng)。它主要由以下四種核心邏輯概念組成:

‍1. File(文件):
HDF5 文件的物理載體,同時(shí)也是邏輯結(jié)構(gòu)的根目錄(通常用 /? 表示)。

‍2. Group(組):
類似于操作系統(tǒng)中的文件夾。一個(gè) Group 可以包含 Dataset(數(shù)據(jù)集)或者其他的 Group,用于對(duì)數(shù)據(jù)進(jìn)行層次化組織。

‍3. Dataset(數(shù)據(jù)集):
類似于操作系統(tǒng)中的文件,是實(shí)際存儲(chǔ)數(shù)據(jù)的地方。Dataset 內(nèi)部通常是同質(zhì)的、多維度的數(shù)值型數(shù)組(類似于 NumPy 數(shù)組)。

‍4. Attribute(屬性):
附加在 Group 或 Dataset 上的元數(shù)據(jù)(Key-Value 對(duì))。常用于保存輔助信息,例如數(shù)據(jù)的單位、采樣率、創(chuàng)建時(shí)間或作者信息等。

h5py 包介紹

?h5py? 提供了對(duì) HDF5 C 語言庫的 Python 包裝。它的核心設(shè)計(jì)理念是:

‍? 將 Group 映射為 Python 的字典(dict):通過鍵值對(duì)的方式訪問子組和數(shù)據(jù)集,如 f['/group_name/dataset_name']?。

‍? 將 Dataset 映射為 NumPy 數(shù)組(ndarray):支持切片操作,僅在需要時(shí)才將數(shù)據(jù)讀入內(nèi)存,非常適合超大文件的延遲加載。

信息整理

‍? GitHub:https://github.com/h5py/h5py

‍? 官網(wǎng):HDF5 for Python

安裝方法

可以使用 pip? 或 conda? 進(jìn)行安裝:

pip install h5py
# 或者使用 conda
conda install h5py

寫入 HDF5 文件

寫入 HDF5 時(shí),推薦使用 Python 的 with? 語句來管理文件生命周期,這樣可以確保即使程序出錯(cuò),文件也能被正確關(guān)閉并寫入磁盤。

創(chuàng)建 Dataset

Dataset是HDF5中存儲(chǔ)實(shí)際數(shù)據(jù)的基本單元。可以創(chuàng)建Dataset,然后再寫入數(shù)據(jù);也可以創(chuàng)建Dataset的同時(shí)寫入數(shù)據(jù),可以直接寫入 NumPy 數(shù)組,h5py? 會(huì)根據(jù) NumPy 的數(shù)據(jù)類型自動(dòng)選擇對(duì)應(yīng)的 HDF5 存儲(chǔ)類型。

import h5py
import numpy as np
# 'w' 模式:寫模式(如果文件存在則覆蓋,不存在則創(chuàng)建)
with h5py.File("data_example.h5", "w") as f:
    # 模擬一些數(shù)據(jù)
    matrix_data = np.random.randn(100, 100)
    # 方式 A:顯式指定數(shù)據(jù)集名稱和數(shù)據(jù)
    f.create_dataset("matrix", data=matrix_data)
    # 方式 B:顯式指定 shape 和 dtype,隨后寫入數(shù)據(jù)
    ds = f.create_dataset("empty_matrix", shape=(10, 10), dtype="float32")
    ds[...] = 1.0  # 填充數(shù)據(jù)

創(chuàng)建 Group

可以通過 create_group? 構(gòu)建多層級(jí)目錄結(jié)構(gòu)。

with h5py.File("data_example.h5", "w") as f:
    # 創(chuàng)建一級(jí)子組
    group_sensor = f.create_group("sensor_data")
    # 在一級(jí)子組下創(chuàng)建二級(jí)子組
    group_gps = group_sensor.create_group("gps")
    # 寫入數(shù)據(jù)到特定的組路徑下
    gps_coords = np.array([[39.9, 116.4], [31.2, 121.5]])
    group_gps.create_dataset("coordinates", data=gps_coords)
    # 也可以直接通過路徑方式隱式創(chuàng)建層級(jí)(h5py 會(huì)自動(dòng)生成缺失的組)
    f.create_dataset("sensor_data/temperature/reading", data=np.array([22.5, 23.0, 22.8]))

寫入 Attribute

屬性可以綁定在任何 Group 或 Dataset 上,用于存儲(chǔ)描述性信息。

with h5py.File("data_example.h5", "w") as f:
    # 創(chuàng)建數(shù)據(jù)集
    ds = f.create_dataset("temperature", data=[22.5, 23.0, 22.8])
    # 寫入屬性(通過 .attrs 字典)
    ds.attrs["unit"] = "Celsius"
    ds.attrs["sensor_model"] = "DHT22"
    ds.attrs["calibration_factor"] = 1.02
    # 給根目錄(File)寫屬性
    f.attrs["author"] = "Antigravity AI"

可擴(kuò)展數(shù)據(jù)集

在實(shí)際應(yīng)用中,數(shù)據(jù)可能是流式產(chǎn)生并不斷追加的。通過設(shè)置 maxshape? 參數(shù),可以創(chuàng)建能夠動(dòng)態(tài)擴(kuò)容的 Dataset。

import h5py
import numpy as np
with h5py.File('resizable.h5', 'w') as f:
    # 創(chuàng)建可擴(kuò)展數(shù)據(jù)集,初始形狀為(100,),最大可擴(kuò)展到無限
    dset = f.create_dataset('expandable', 
                           shape=(100,), 
                           maxshape=(None,),  # None表示該維度可無限擴(kuò)展
                           dtype='float64')
    dset[:] = np.arange(100)
    # 擴(kuò)展數(shù)據(jù)集
    dset.resize((200,))
    dset[100:] = np.arange(100, 200)
    # 創(chuàng)建二維可擴(kuò)展數(shù)據(jù)集
    dset2 = f.create_dataset('expandable_2d',
                            shape=(10, 20),
                            maxshape=(None, 20),  # 只有第一維可擴(kuò)展
                            dtype='int32')
    dset2[:] = np.arange(200).reshape(10, 20)
    # 追加新的行
    dset2.resize((15, 20))
    dset2[10:] = np.arange(200, 300).reshape(5, 20)

壓縮存儲(chǔ)

針對(duì)大規(guī)模數(shù)據(jù),HDF5 提供了內(nèi)置的數(shù)據(jù)壓縮機(jī)制。這通常配合分塊(chunks?)使用,能夠極大地減少磁盤空間消耗,且在讀取時(shí)可以自動(dòng)解壓。

with h5py.File("compressed_example.h5", "w") as f:
    large_data = np.random.randn(1000, 1000)
    # 啟用 gzip 壓縮,設(shè)置壓縮級(jí)別為 4(范圍 1-9,數(shù)值越大壓縮率越高,但越耗時(shí))
    f.create_dataset(
        "compressed_matrix", 
        data=large_data, 
        compression="gzip", 
        compression_opts=4, 
        chunks=(100, 100) # 指定分塊形狀
    )

此外還可以使用第三方庫 hdf5plugin? 可以使用更高性能的壓縮算法(如 Zstd、LZ4 等),具體見Python 如何壓縮HDF5文件

?? Note
為什么壓縮時(shí)需要分塊
在默認(rèn)情況下,如果不指定壓縮或擴(kuò)展,HDF5 會(huì)采用連續(xù)存儲(chǔ)(Contiguous Storage)。也就是說,整個(gè)數(shù)據(jù)集在磁盤上就是一塊完整、不間斷的二進(jìn)制數(shù)據(jù)流??梢栽诓粔嚎s、不擴(kuò)容時(shí)獲得最快的直接讀取速度和最低的系統(tǒng)開銷。
而壓縮后因?yàn)閿?shù)據(jù)不再是等寬排列時(shí),連續(xù)存儲(chǔ)就有問題了
‍? 無法直接計(jì)算數(shù)據(jù)偏移量(尋址失效)
‍ 數(shù)據(jù)壓縮后,原本固定大小的數(shù)組元素(例如每個(gè) float? 占 4 字節(jié))變成了?變長(zhǎng)數(shù)據(jù)?。
‍ ‍ ○ 由于數(shù)據(jù)不再是等寬排列,你無法再通過公式直接計(jì)算出 A[100][100]? 在磁盤上的第幾個(gè)字節(jié)。
‍ ‍ ○ 如果是連續(xù)存儲(chǔ),你必須把這 100 行之前的所有數(shù)據(jù)全部讀取并解壓,才能找到目標(biāo)元素。讀取一小塊數(shù)據(jù)就要解壓整個(gè)文件,這在處理大文件時(shí)性能是不可接受的。
‍? 局部的修改會(huì)引發(fā)“全文件重寫”
‍ 如果修改了 A[50][50]? 的值,壓縮后這部分?jǐn)?shù)據(jù)的字節(jié)大小很可能會(huì)發(fā)生變化(變大或變?。?。如果是連續(xù)存儲(chǔ),為了塞下變大后的數(shù)據(jù),你就必須將它后面所有的數(shù)據(jù)在磁盤上整體向后平移;如果變小了,則需要向前收縮。這會(huì)導(dǎo)致極其高昂的磁盤 I/O 成本。
所以需要分塊,可以將多維數(shù)組分割成大小相同的子塊(Chunks),每個(gè)子塊在磁盤上獨(dú)立存放,并通過一個(gè) B 樹(B-Tree) 索引來管理。
優(yōu)勢(shì)
‍1. ?局部解壓,提升速度?: 當(dāng)讀取 A[100][100]? 時(shí),HDF5 查閱 B 樹索引,得知該元素屬于分塊 (1,0)?,只需從磁盤中取出分塊 (1,0)? 的 9KB 壓縮數(shù)據(jù)進(jìn)行解壓即可。?其余無關(guān)的分塊不需要解壓?。
‍2. ?靈活應(yīng)對(duì)變長(zhǎng)數(shù)據(jù)?: 每個(gè)塊獨(dú)立壓縮后大小不同(如一個(gè)是 12KB,一個(gè)是 15KB),但這無所謂。HDF5 只需要在 B 樹索引中更新該塊的“物理地址”和“壓縮后大小”即可,不需要移動(dòng)磁盤上的其他塊。
‍3. ?支持動(dòng)態(tài)追加(Resize)?: 當(dāng)數(shù)據(jù)集擴(kuò)容時(shí),HDF5 只需要在磁盤空白處寫入新的分塊,并將其注冊(cè)到 B 樹索引中。各個(gè)分塊在磁盤上不需要連續(xù),徹底解決了擴(kuò)容時(shí)的空間覆蓋沖突。

保存字符串

HDF5 原生不支持 Python 3 的可變長(zhǎng)度 Unicode 字符串。在 h5py? 中,推薦使用特定的數(shù)據(jù)類型來處理字符串。

with h5py.File("strings_example.h5", "w") as f:
    # 1. 單個(gè)/少量變長(zhǎng) UTF-8 字符串
    utf8_type = h5py.string_dtype(encoding="utf-8")
    # 2. 寫入字符串?dāng)?shù)組
    words = np.array(["你好", "HDF5", "Python 數(shù)據(jù)科學(xué)"], dtype=object)
    ds = f.create_dataset("chinese_words", (3,), dtype=utf8_type)
    ds[:] = words
    # 3. 簡(jiǎn)寫方式(通常可以直接傳入字節(jié)串 bytes,或者使用 asstr() 進(jìn)行讀寫)
    f.create_dataset("ascii_bytes", data=[b"hello", b"world"])

讀取 HDF5 文件

遞歸遍歷文件結(jié)構(gòu)

由于 HDF5 具有樹狀結(jié)構(gòu),我們可以使用 visit? 或 visititems? 方法對(duì)文件中的所有節(jié)點(diǎn)(Group 和 Dataset)進(jìn)行深度優(yōu)先遍歷。

import h5py
def print_structure(name, obj):
    """
    回調(diào)函數(shù):
    name: 節(jié)點(diǎn)的相對(duì)路徑 (如 '/sensor_data/temperature')
    obj: HDF5 Group 或 Dataset 對(duì)象
    """
    indent = "  " * name.count("/")
    if isinstance(obj, h5py.Dataset):
        print(f"{indent}?? Dataset: {name} (shape={obj.shape}, dtype={obj.dtype})")
        # 打印屬性
        if len(obj.attrs) > 0:
            for k, v in obj.attrs.items():
                print(f"{indent}    ??? {k}: {v}")
    elif isinstance(obj, h5py.Group):
        print(f"{indent}?? Group: {name}")
# 以只讀模式 'r' 打開文件
with h5py.File("data_example.h5", "r") as f:
    print("--- 文件樹形結(jié)構(gòu) ---")
    f.visititems(print_structure)

讀取全部數(shù)據(jù)

當(dāng)我們確定數(shù)據(jù)集較小,可以直接一次性讀入內(nèi)存轉(zhuǎn)換為標(biāo)準(zhǔn)的 NumPy 數(shù)組。

with h5py.File("data_example.h5", "r") as f:
    # 檢查鍵是否存在
    if "matrix" in f:
        # 使用切片 [:] 讀取全部數(shù)據(jù)到內(nèi)存中,得到一個(gè) NumPy ndarray
        data = f["matrix"][:]
        print("數(shù)據(jù)類型:", type(data))
        print("數(shù)據(jù)形狀:", data.shape)

讀取部分?jǐn)?shù)據(jù)(切片/延遲加載)

這是 HDF5 最核心的優(yōu)勢(shì)之一。如果文件大小為數(shù)吉字節(jié)(GB),你只需讀取其中的某一小塊數(shù)據(jù),而無需將其全部加載至內(nèi)存。

with h5py.File("data_example.h5", "r") as f:
    dataset = f["matrix"] # 此時(shí)只是獲取了數(shù)據(jù)集的引用,并未真正讀取數(shù)據(jù)
    # 僅讀取前 10 行的前 5 列數(shù)據(jù)到內(nèi)存
    sub_data = dataset[0:10, 0:5]
    print("局部數(shù)據(jù)形狀:", sub_data.shape)

小結(jié)

常用操作對(duì)照表

下面是 h5py? 中最常用操作的方法整理,便于在實(shí)際開發(fā)中快速檢索:

操作分類目標(biāo)操作常用代碼示例說明
打開/關(guān)閉打開文件(讀)?f = h5py.File('data.h5', 'r')?建議使用 with? 語法自動(dòng)管理關(guān)閉
打開文件(寫)?f = h5py.File('data.h5', 'w')?會(huì)覆蓋已存在的文件
追加模式打開?f = h5py.File('data.h5', 'a')?可讀可寫,文件不存在則創(chuàng)建
層級(jí)組織創(chuàng)建 Group?g = f.create_group('grp')?返回 Group 對(duì)象
判斷路徑是否存在?'grp/dset' in f?返回布爾值,支持相對(duì)或絕對(duì)路徑
刪除組或數(shù)據(jù)集?del f['grp/dset']?從文件中刪除節(jié)點(diǎn)和數(shù)據(jù)引用
數(shù)據(jù)集寫入基礎(chǔ) Dataset 創(chuàng)建?f.create_dataset('ds', data=array)?基于現(xiàn)有 NumPy 數(shù)組直接創(chuàng)建
空 Dataset 初始化?f.create_dataset('ds', shape=(100,), dtype='i')?預(yù)分配空間,后續(xù)賦值寫入
啟用壓縮?f.create_dataset('ds', data=arr, compression='gzip')?默認(rèn)等級(jí)為 4,利于節(jié)省磁盤空間
創(chuàng)建可追加 Dataset?f.create_dataset('ds', shape=(0, 10), maxshape=(None, 10))?必須配合 chunks=True? 或指定分塊
改變 Dataset 大小?dset.resize((new_size, 10))?用于追加數(shù)據(jù)時(shí)的擴(kuò)容操作
屬性/元數(shù)據(jù)寫入屬性?obj.attrs['key'] = value??obj? 可以是 File, Group, Dataset
讀取屬性?value = obj.attrs['key']?返回對(duì)應(yīng)的值(支持標(biāo)量或數(shù)組)
讀取操作遍歷結(jié)構(gòu)?f.visititems(callback_func)?遞歸遍歷,每個(gè)節(jié)點(diǎn)調(diào)用一次回調(diào)函數(shù)
讀取完整數(shù)據(jù)?arr = f['ds'][:]?切片 [:]? 觸發(fā)真正的磁盤 I/O 讀入內(nèi)存
切片(讀取部分)?arr = f['ds'][0:10, 2:5]?僅加載切片區(qū)間數(shù)據(jù),優(yōu)化內(nèi)存
字符串解碼讀取?s = f['str_ds'].asstr()[0]?對(duì)變長(zhǎng) UTF-8 字符串?dāng)?shù)據(jù)集進(jìn)行解碼讀取

相關(guān)筆記

‍? 大文件存儲(chǔ)格式丨HDF5

‍? 如何預(yù)覽HDF5文件:使用HDFView

到此這篇關(guān)于Python操作處理 HDF5 文件的詳細(xì)操作的文章就介紹到這了,更多相關(guān)Python HDF5 文件 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

紫阳县| 蕉岭县| 韩城市| 钟山县| 宣化县| 南澳县| 新源县| 丁青县| 彭山县| 靖边县| 定西市| 张家港市| 黄龙县| 昌图县| 阿拉善右旗| 疏勒县| 井冈山市| 革吉县| 元谋县| 时尚| 景宁| 清水县| 伊吾县| 藁城市| 民乐县| 苍山县| 綦江县| 澎湖县| 大港区| 八宿县| 长海县| 浏阳市| 巴青县| 平安县| 东兴市| 阳高县| 美姑县| 齐河县| 广东省| 阳信县| 腾冲县|