Сохраните строку в наборе данных h5py, используя тип «массив 8-битных целых (80)» - PullRequest
0 голосов
/ 21 марта 2019

Я хочу создать h5py набор данных "string" (например, "A"), используя тип данных "массив 8-битных целых (80)" (как показано в HDFView, см. здесь ).Каждое целое число этого массива длиной 80 на самом деле ord(x) соответствующего символа этой строки.Например, Top хранится как 84 111 112 0 0 0 ..., всего 80 int8.

Требуемый набор данных должен выглядеть следующим образом

DATASET "NOM" {
                     DATATYPE  H5T_ARRAY { [80] H5T_STD_I8LE }
                     DATASPACE  SIMPLE { ( 1 ) / ( 1 ) }
                     DATA {
                     (0): [ 84, 111, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
                     }

Однако я не могу создатьэтот набор данных, используя h5py.Использование стандартного массива numpy дает это

DATASET "NOM" {
                     DATATYPE  H5T_STD_I8LE
                     DATASPACE  SIMPLE { ( 1, 80 ) / ( 1, 80 ) }
                     DATA {
                     (0,0): 84, 111, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                     (0,15): 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                     (0,31): 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                     (0,47): 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                     (0,63): 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                     (0,79): 0
                     }
                  }

Так что же нужно data и dtype, если моя строка, скажем, "Top".

.create_dataset("NOM", data=data, dtype=dtype)

Согласноhttps://github.com/h5py/h5py/issues/955, возможно, мне нужно использовать интерфейс более низкого уровня ...?

Спасибо!

Решение

Проблема заключается в том, что если мы создадим набор данных numpydata перед записью с использованием .create_dataset("NOM", data=data), внутренне numpy всегда будет интерпретировать мой тип данных 80int8 как массив 1d int8

dtype = np.dtype("80int8")
x = np.array(2, dtype=dtype)
# x.dtype = dtype('int8')

Таким образом, решение заключается в объявлении набора данных с помощьюсначала необходимо dtype, затем заполните данные.

dataset = gro.create_dataset("NOM", (len(nom),), dtype="80int8")
for i in range(len(nom)):
    nom_80 = nom[i] + "\x00" * (80 - len(nom[i]))  # make nom 80 characters
    dataset[i] = [ord(x) for x in nom_80]
# dataset.dtype = dtype(('i1', (80,)))

1 Ответ

0 голосов
/ 21 марта 2019

Создайте массив uint8 правильного размера и содержания:

In [417]: x = np.zeros(80, dtype='uint8')                                                 
In [419]: x[:3]=[ord(i) for i in 'Top']                                                                                                                                
In [421]: ds1=hf.create_dataset('other4', data=x) 

Подход структурированного массива:

In [486]: dt = np.dtype([('f0','80int8')])                                                
In [487]: dt                                                                              
Out[487]: dtype([('f0', 'i1', (80,))])
In [488]: x = np.zeros(1, dt)                                                             
In [489]: x['f0'][0][:3]=[ord(i) for i in 'Top']                                          
In [490]: x                                                                               
Out[490]: 
array([([ 84, 111, 112,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0],)],
      dtype=[('f0', 'i1', (80,))])
In [491]: ds1=hf.create_dataset('st1', data=x)                                            
In [492]: ds1                                                                             
Out[492]: <HDF5 dataset "st1": shape (1,), type "|V80">

производит

   DATASET "st1" {
      DATATYPE  H5T_COMPOUND {
         H5T_ARRAY { [80] H5T_STD_I8LE } "f0";
      }
      DATASPACE  SIMPLE { ( 1 ) / ( 1 ) }
      DATA {
      (0): {
            [ 84, 111, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
         }
      }
   }
...