Как перебрать тип данных, чтобы получить связанные значения? - PullRequest
0 голосов
/ 11 июня 2019

В настоящее время я обнаруживаю библиотеку HDf5 на Python, и у меня возникла проблема.У меня есть набор данных с этим макетом:

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 'не повторяется». У вас есть идеи, как это обрабатывать?Я надеюсь, что мой вопрос ясен.

Ответы [ 3 ]

0 голосов
/ 12 июня 2019

Для завершения решения, добавленного 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)
0 голосов
/ 12 июня 2019

Арно, хорошо, я вижу, вы используете h5py. Я не понимаю, что вы подразумеваете под " Я не могу перебрать набор данных ". Вы можете перебирать строки или столбцы / поля. Вот пример для демонстрации с помощью h5py.

Показывает 4 способа извлечения данных из набора данных, последний итерируется):

  1. Считывание всего набора данных HDF5 в массив np
  2. Затем прочитайте 1 столбец из этого массива в другой массив
  3. Считать 1 столбец из набора данных HDF5 в виде массива
  4. Зацикливать столбцы набора данных HDF5 и читать по одному за раз как массив

Обратите внимание, что возврат из .dtype.names повторяется. Вам не нужно создавать список (если он вам не нужен для других целей). Кроме того, HDF5 поддерживает смешанные типы в наборах данных, поэтому вы можете получить dtype с значениями типа int, float и string (это будет массив записей).

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)
0 голосов
/ 11 июня 2019

Без ваших данных сложно предложить конкретные решения. Вот очень простой пример, который имитирует вашу схему данных, используя pytables (& numpy). Сначала создается файл HDF5 с таблицей с именем DATASET1 в группе GROUP1 . 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", если вам нужно только прочитать данные.

...