簡體   English   中英

如何從 a.hdf5 文件表中提取列名並根據指定的列名提取特定行數據?

[英]How do I extract the column names from a .hdf5 file table and extract specific row data based on a specified column name?

下面是 my.hdf5 文件中數據分支的屏幕截圖。 我正在嘗試從這個特定的 BlinkStartEvent 段中提取現有的列名(即experiment_id、session_id ....)。

在此處輸入圖像描述

我有以下代碼可以訪問這部分數據並提取數字數據。 但由於某種原因,我無法提取相應的列名,我希望將 append 放到一個單獨的列表中,這樣我就可以從整個數據集中創建一個字典。 我以為.keys() 應該這樣做,但事實並非如此。

import h5py

def traverse_datasets(hdf_file):

    def h5py_dataset_iterator(g, prefix=''):
        for key in g.keys():
            #print(key)
            item = g[key]
            path = f'{prefix}/{key}'
            if isinstance(item, h5py.Dataset): # test for dataset
                yield (path, item)
            elif isinstance(item, h5py.Group): # test for group (go down)
                yield from h5py_dataset_iterator(item, path)

    for path, _ in h5py_dataset_iterator(hdf_file):
        yield path

with h5py.File(filenameHDF[0], 'r') as f:
    for dset in traverse_datasets(f):
        if str(dset[-15:]) == 'BlinkStartEvent':
            print('-----Path:', dset)                     # path that leads to the data
            print('-----Shape:', f[dset].shape)           #the length dimension of the data
            print('-----Data type:', f[dset].dtype)       #prints out the unicode for all columns
            data2 = f[dset][()]    # The entire dataset
            # print('Check column names', f[dset].keys()) # I tried this but I got a AttributeError: 'Dataset' object has no attribute 'keys' error

我得到以下 output:

-----Path: /data_collection/events/eyetracker/BlinkStartEvent
-----Shape: (220,)
-----Data type: [('experiment_id', '<u4'), ('session_id', '<u4'), ('device_id', '<u2'), ('event_id', '<u4'), ('type', 'u1'), ('device_time', '<f4'), ('logged_time', '<f4'), ('time', '<f4'), ('confidence_interval', '<f4'), ('delay', '<f4'), ('filter_id', '<i2'), ('eye', 'u1'), ('status', 'u1')]
Traceback (most recent call last):

  File "C:\Users\angjw\Dropbox\NUS PVT\Analysis\PVT analysis_hdf5access.py", line 64, in <module>
    print('Check column names', f[dset].keys())

AttributeError: 'Dataset' object has no attribute 'keys'

我在這里做錯了什么?

此外,是否有更有效的方法來訪問數據,以便我可以做一些(假設的)事情,比如:

data2[0]['experiment_id'] = 1 
data2[1]['time'] = 78.35161
data2[2]['logged_time'] = 80.59253

而不是通過為每一行數據設置字典的過程來 go ?

你很近。 數據集的.dtype將數據集作為 NumPy dtype 提供給您。 添加.descr將其作為(字段名稱、字段類型)元組列表返回。 請參閱下面的代碼以打印循環內的字段名稱:

for (f_name,f_type) in f[dset].dtype.descr:
    print(f_name)

有比為每一行數據創建字典更好的方法來處理 HDF5 數據(除非您出於某種原因絕對想要字典)。 h5py 旨在處理類似於 NumPy arrays 的數據集值。 (但是,並非所有 NumPy 操作都適用於 h5py 數據集對象)。 以下代碼訪問數據並返回 2 個相似(但略有不同)的數據對象。

# this returns a h5py dataset object that behaves like a NumPy array:
dset_obj = f[dset]  
# this returns a NumPy array:
dset_arr = f[dset][()] 

您可以使用標准 NumPy 切片表示法(您可以使用字段名稱和行值)從 object 切片數據。 繼續...

# returns row 0 from field 'experiment_id'
val0 = dset_obj[0]['experiment_id']
# returns row 1 from field 'time'
val1 = dset_obj[1]['time']
# returns row 2 from field 'logged_time'
val2 = dset_obj[2]['logged_time']

(如果您將dset_obj替換為上面的dset_arr ,您將獲得相同的值。)您還可以像這樣對整個字段/列進行切片:

# returns field 'experiment_id' as a NumPy array
expr_arr = dset_obj['experiment_id']
# returns field 'time' as a NumPy array
time_arr = dset_obj['time']
# returns field 'logged_time' as a NumPy array
logtime_arr = dset_obj['logged_time']

那應該回答您最初的問題。 如果沒有,請添加評論(或修改帖子),我會更新我的答案。

我之前的回答使用了 h5py package(與您的代碼相同的 package)。 還有另一個我喜歡與 HDF5 數據一起使用的 Python package:PyTables(又名表)。 兩者非常相似,並且各自具有獨特的優勢。

  • h5py嘗試盡可能接近 map 將 HDF5 功能集設置為 NumPy。 它使用 Python 字典語法來迭代 object 名稱和值。 因此,如果您熟悉 NumPy,則很容易學習。 否則,您必須學習一些 NumPy 基礎知識(例如詢問 dtype)。 同質數據作為np.array返回,異構數據(如您的)作為np.recarray返回。
  • PyTables在 HDF5 和 NumPy 之上構建了一個額外的抽象層。 我喜歡的兩個獨特功能是:1) 對節點(組或數據集)進行遞歸迭代,因此不需要自定義數據集生成器,以及 2) 使用“表”object 訪問異構數據,該表具有比基本 NumPy recarray 更多的方法方法。 (此外,它可以對表進行復雜的查詢,具有先進的索引功能,而且速度很快!)

為了比較它們,我用 PyTables 重寫了你的 h5py 代碼,這樣你就可以“看到”差異。 我在您的問題中合並了所有操作,並在我之前的答案中包含了等效的調用。 需要注意的差異:

  • f.walk_nodes()方法是替換生成器的內置方法。 但是,它返回 object(在這種情況下為表 object),而不是表(數據集)名稱。 因此,使用 object 而不是名稱時,代碼略有不同。
  • 使用Table.read()將數據加載到 NumPy(記錄)數組中。 不同的示例顯示使用字段名稱讀取整個表或單個列。

下面的代碼:

import tables as tb

with tb.File(filenameHDF[0], 'r') as f:
    for tb_obj in f.walk_nodes('/','Table'):
        if str(tb_obj.name[-15:]) == 'BlinkStartEvent':
            print('-----Name:', tb_obj.name)            # Table name without the path            
            print('-----Path:', tb_obj._v_pathname)     # path that leads to the data
            print('-----Shape:', tb_obj.shape)          # the length dimension of the data
            print('-----Data type:', tb_obj.dtype)      # prints out the np.dtype for all column names/variable types
            print('-----Field/Column names:', tb_obj.colnames)  #prints out the names of all columns as a list
            
            data2 = tb_obj.read()    # The entire Table (dataset) into array data2
            
            # returns field 'experiment_id' as a NumPy (record) array
            expr_arr = tb_obj.read(field='experiment_id')
            # returns field 'time' as a NumPy (record) array
            time_arr = tb_obj.read(field='time')
            # returns field 'logged_time' as a NumPy (record) array
            logtime_arr = tb_obj.read(field='logged_time')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM