【问题标题】:How to iterate on datatype to get associated values?如何迭代数据类型以获取关联值?
【发布时间】:2019-10-25 23:41:36
【问题描述】:

我目前正在发现 Python 中的 HDf5 库,但我遇到了一些问题。我有一个具有这种布局的数据集:

GROUP "GROUP1" {
                  DATASET "DATASET1" {
                     DATATYPE  H5T_COMPOUND {
                        H5T_STD_I64LE "DATATYPE1";
                        H5T_STD_I64LE "DATATYPE2";
                        H5T_STD_I64LE "DATATYPE3";
                     }
                     DATASPACE  SIMPLE { ( 3 ) / ( 3 ) }
                     DATA {
                     (0): {
                           1,
                           2,
                           3

我正在尝试在数据集中进行迭代以获取与每个数据类型关联的值并将它们复制到文本文件中。 (例如,“1”是“DATATYPE1”的关联值。)以下脚本确实有效:

new_file  = open('newfile.txt', 'a') 
for i in range(len(dataset[...])):
 new_file.write('Ligne '+ str(i)+" "+":"+" ") 
   for j in range(len(dataset[i,...])):
     new_file.write(str(dataset[i][j]) + "\n")

但它不是那么干净......所以我尝试通过按名称调用数据类型来获取值。我找到的最接近的脚本如下:

for attribute in group.attrs:
    print group.attrs[attribute]

不幸的是,尽管我尝试过,但它不适用于数据类型:

检查数据类型导致数据集

   for data.dtype in dataset.dtype:
#then print datatypes
       print dataset.dtype[data.dtype

后备错误消息是“numpy.dtype' object is not iterable”。 请问您知道如何处理吗?我希望我的问题很清楚。

【问题讨论】:

  • 我们实际上更希望发帖者不要在他们的问题中加入额外的措辞,如问候和“提前致谢”。
  • 您应该使用 HDF5 模块之一通过 Python 访问此文件:h5py 和 pytables 是最常见的。
  • 好的,抱歉。我实际上使用'import h5py'。

标签: python hdf5


【解决方案1】:

没有您的数据,很难提供具体的解决方案。这是一个非常简单的示例,它使用 pytables (& numpy) 模拟您的数据模式。首先,它创建 HDF5 文件,在组 GROUP1 下具有名为 DATASET1 的表。 DATASET1 在每一行中有 3 个 int 值,名为:DATATYPE1、DATATYPE2 和 DATATYPE3。 ds1.append() 函数将数据行添加到表中(一次 1 行)。
数据创建后,walk_nodes()用于遍历HDF5文件结构,打印表的节点名和dtypes。

import tables as tb
import numpy as np

with tb.open_file("SO_56545586.h5", mode = "w") as h5f:

    ds1 = h5f.create_table('/GROUP1', 'DATASET1', 
                           description=np.dtype([('DATATYPE1', int),('DATATYPE2', int),('DATATYPE3', int)]), 
                           createparents=True)
    for row in range(5) :
        row_vals = [ (row, row+1, row*2), ]
        ds1.append(row_vals)

## This section walks the file strcuture (groups and datasets), printing node names and dtype for tables:

    for this_node in h5f.walk_nodes('/'):
        print (this_node)
        if isinstance(this_node, tb.Table) :
            print (this_node.dtype)    

注意:请勿在打开现有文件时使用mode = "w"。它将创建一个新文件(覆盖现有文件)。如果您需要追加数据,请使用mode = "a"mode = "r+",如果您只需要读取数据,请使用mode = "r"

【讨论】:

  • 谢谢你的回答。它似乎对我有用!我终于找到了另一种方法,我将在下面解释之前关闭主题。
【解决方案2】:

要完成 kcw78 添加的解决方案,我还发现这个脚本也可以工作。因为我无法遍历数据集,所以我将数据集复制到了一个新数组中:

dataset = file['path_to_dataset']

data = np.array(dataset) # Create a new array filled with dataset values as numpy.
print(data)  

ls_column = list(data.dtype.names) # Get a list with datatypes associated to each data values.
print(ls_column) # Show layout of datatypes associated to each previous data values. 

# Create an array filled with same datatypes rather than same subcases. 
for col in ls_column: 

    k = data[col] # example : k=data['DATATYPE1'], k=data['DATATYPE2']  
    print(k)

【讨论】:

    【解决方案3】:

    Arnaud,好的,我看到你正在使用 h5py。 我不明白您所说的“我无法遍历数据集”是什么意思。您可以遍历行或列/字段。 这是一个使用 h5py 演示的示例。

    它显示了从数据集中提取数据的 4 种方法,最后一种是迭代):

    1. 将整个 HDF5 数据集读取到 np 数组中
    2. 然后从该数组中读取 1 列到另一个数组中
    3. 从 HDF5 数据集中读取 1 列作为数组
    4. 循环遍历 HDF5 数据集列,并以数组的形式一次读取 1 个

    请注意,.dtype.names 的返回是可迭代的。您不需要创建列表(除非您需要它用于其他目的)。此外,HDF5 支持数据集中的混合类型,因此您可以获得具有 int、float 和 string 值的 dtype(它将是一个记录数组)。

    import h5py
    import numpy as np
    
    with h5py.File("SO_56545586.h5", "w") as h5f:
    
        # create empty dataset 'DATASET1' in group '/GROUP1'
        # dyte argument defines names and types
        ds1 = h5f.create_dataset('/GROUP1/DATASET1', (10,), 
                  dtype=np.dtype([('DATATYPE1', int),('DATATYPE2', int),('DATATYPE3', int)]) )
    
        for row in range(5) :  # load some arbitrary data into the dataset
            row_vals = [ (row, row+1, row*2), ]
            ds1[row] = row_vals
    
        # to read the entire dataset as an array
        ds1_arr = h5f['/GROUP1/DATASET1'][:] 
        print (ds1_arr.dtype) 
    
        # to read 1 column from ds1_arr as an array
        ds1_col1 = ds1_arr[:]['DATATYPE1'] 
        print ('for DATATYPE1 from ds1_arr, dtype=',ds1_col1.dtype)
    
        # to read 1 HDF5 dataset column as an array
        ds1_col1 = h5f['/GROUP1/DATASET1'][:,'DATATYPE1'] 
        print ('for DATATYPE1 from HDF5, dtype=',ds1_col1.dtype)
    
        # to loop thru HDF5 dataset columns and read 1 at a time as an array
        for col in h5f['/GROUP1/DATASET1'].dtype.names :
            print ('for ', col, ', dtype=',h5f['/GROUP1/DATASET1'][col].dtype) 
            col_arr = h5f['/GROUP1/DATASET1'][col][:]
            print (col_arr.shape)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-09-26
      • 2014-11-30
      • 1970-01-01
      • 1970-01-01
      • 2013-12-14
      • 1970-01-01
      • 2015-09-09
      相关资源
      最近更新 更多