Как определить отдельный тип данных для каждого столбца HDF5 с помощью h5py - PullRequest
0 голосов
/ 08 марта 2020

Я проверил разные решения, но не мог понять, как применить их к многомерным массивам. Чтобы быть точным, мой код приводит к большему массиву, чем это должно быть, как показано на рисунке ниже:

import h5py
import pandas as pd
import numpy as np

data = [[1583663558450195, -7.063664436340332, -6.2776079177856445, -4.206898212432861, -4.206898212432861], [1583663558450195, -7.063664436340332, -6.2776079177856445, -4.206898212432861, -4.206898212432861], [1583663558450195, -7.063664436340332, -6.2776079177856445, -4.206898212432861, -4.206898212432861], [1583663558450195, -7.063664436340332, -6.2776079177856445, -4.206898212432861, -4.206898212432861], [1583663558450195, -7.063664436340332, -6.2776079177856445, -4.206898212432861, -4.206898212432861], [1583663558450195, -7.063664436340332, -6.2776079177856445, -4.206898212432861, -4.206898212432861], [1583663558450195, -7.063664436340332, -6.2776079177856445, -4.206898212432861, -4.206898212432861], [1583663558450195, -7.063664436340332, -6.2776079177856445, -4.206898212432861, -4.206898212432861], [1583663558450195, -7.063664436340332, -6.2776079177856445, -4.206898212432861, -4.206898212432861], [1583663558450195, -7.063664436340332, -6.2776079177856445, -4.206898212432861, -4.206898212432861]]

df = pd.DataFrame(data)

hf = h5py.File('dtype.h5', 'w')

dataTypes = np.dtype([('ts', 'u8'), ('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('temp', 'f4')])
ds = hf.create_dataset('Acceleration', data=df.astype(dataTypes))

enter image description here

Я хотел бы чтобы сделать это так, где столбцы uint64, 4x float32 соответственно:

                 ts         x         y         z      temp
0  1583663558450195 -7.063664 -6.277608 -4.206898 -4.206898
1  1583663558450195 -7.063664 -6.277608 -4.206898 -4.206898
2  1583663558450195 -7.063664 -6.277608 -4.206898 -4.206898
3  1583663558450195 -7.063664 -6.277608 -4.206898 -4.206898
4  1583663558450195 -7.063664 -6.277608 -4.206898 -4.206898
5  1583663558450195 -7.063664 -6.277608 -4.206898 -4.206898
6  1583663558450195 -7.063664 -6.277608 -4.206898 -4.206898
7  1583663558450195 -7.063664 -6.277608 -4.206898 -4.206898
8  1583663558450195 -7.063664 -6.277608 -4.206898 -4.206898
9  1583663558450195 -7.063664 -6.277608 -4.206898 -4.206898

Ответы [ 2 ]

1 голос
/ 09 марта 2020

Этот вопрос сложнее, чем кажется на первый взгляд. Первоначально я думал, что смогу применить тот же метод, что и мой ответ на ваш предыдущий вопрос SO 60562311: определить отдельные типы данных для каждого столбца . Тем не менее, он имеет некоторые тонкие различия:

  1. Эти данные представляют собой список списков VS 5x5 NumPy массив
  2. Эти данные имеют смешанный тип (Ints и Floats) VS все Число с плавающей точкой
  3. Эти данные имеют более значимые значения, чем предыдущий пример

Как это изменит процедуру?

  • Список списков можно преобразовать в массив NumPy с помощью np.array(data) Однако это не решает проблему полностью. Вы все равно получите дублированные столбцы.
  • Вам также необходимо изменить тип объекта в объявлении dtype. f4 должно быть f8, а u8 должно быть uint16

Внесите эти изменения, и все будет работать как мой предыдущий ответ. Смотрите обновление вашего исходного кода ниже.

dataTypes = np.dtype([('ts', 'uint16'), ('x', 'f8'), 
            ('y', 'f8'), ('z', 'f8'), ('temp', 'f8')])
# create array from list of lists
d_arr = np.array(data) 
# create record array
rec_arr = np.rec.array(d_arr, dtype=dataTypes)
with h5py.File('dtype.h5', 'w') as hf:
    ds = hf.create_dataset('Acceleration', data=rec_arr)
1 голос
/ 08 марта 2020

Ваш df:

In [370]: df                                                                                   
Out[370]: 
                  0         1         2         3         4
0  1583663558450195 -7.063664 -6.277608 -4.206898 -4.206898
1  1583663558450195 -7.063664 -6.277608 -4.206898 -4.206898
2  1583663558450195 -7.063664 -6.277608 -4.206898 -4.206898
3  1583663558450195 -7.063664 -6.277608 -4.206898 -4.206898
...

df.astype(dataTypes) дает мне TypeError (мой pd не последний).

In [373]: df.to_records()                                                                      
Out[373]: 
rec.array([(0, 1583663558450195, -7.06366444, -6.27760792, -4.20689821, -4.20689821),
           (1, 1583663558450195, -7.06366444, -6.27760792, -4.20689821, -4.20689821),
           (2, 1583663558450195, -7.06366444, -6.27760792, -4.20689821, -4.20689821),
           (3, 1583663558450195, -7.06366444, -6.27760792, -4.20689821, -4.20689821),
           (4, 1583663558450195, -7.06366444, -6.27760792, -4.20689821, -4.20689821),
           (5, 1583663558450195, -7.06366444, -6.27760792, -4.20689821, -4.20689821),
           (6, 1583663558450195, -7.06366444, -6.27760792, -4.20689821, -4.20689821),
           (7, 1583663558450195, -7.06366444, -6.27760792, -4.20689821, -4.20689821),
           (8, 1583663558450195, -7.06366444, -6.27760792, -4.20689821, -4.20689821),
           (9, 1583663558450195, -7.06366444, -6.27760792, -4.20689821, -4.20689821)],
          dtype=[('index', '<i8'), ('0', '<i8'), ('1', '<f8'), ('2', '<f8'), ('3', '<f8'), ('4', '<f8')])

Этот массив должен сохранить с h5py.

to_records имеет параметры, которые могут создать что-то ближе к вашему dataTypes. Я позволю вам изучить их.

Но с последней реструктуризацией recfunctions мы можем создать структурированный массив с:

In [385]: import numpy.lib.recfunctions as rf                                                  
In [386]: rf.unstructured_to_structured(np.array(data), dataTypes)                             
Out[386]: 
array([(1583663558450195, -7.0636644, -6.277608, -4.206898, -4.206898),
       (1583663558450195, -7.0636644, -6.277608, -4.206898, -4.206898),
       (1583663558450195, -7.0636644, -6.277608, -4.206898, -4.206898),
       (1583663558450195, -7.0636644, -6.277608, -4.206898, -4.206898),
       (1583663558450195, -7.0636644, -6.277608, -4.206898, -4.206898),
       (1583663558450195, -7.0636644, -6.277608, -4.206898, -4.206898),
       (1583663558450195, -7.0636644, -6.277608, -4.206898, -4.206898),
       (1583663558450195, -7.0636644, -6.277608, -4.206898, -4.206898),
       (1583663558450195, -7.0636644, -6.277608, -4.206898, -4.206898),
       (1583663558450195, -7.0636644, -6.277608, -4.206898, -4.206898)],
      dtype=[('ts', '<u8'), ('x', '<f4'), ('y', '<f4'), ('z', '<f4'), ('temp', '<f4')])

np.array(data) is (10,5) массив с плавающей точкой.

In [388]: pd.DataFrame(_386)                                                                   
Out[388]: 
                 ts         x         y         z      temp
0  1583663558450195 -7.063664 -6.277608 -4.206898 -4.206898
1  1583663558450195 -7.063664 -6.277608 -4.206898 -4.206898
2  1583663558450195 -7.063664 -6.277608 -4.206898 -4.206898
 ...
...