Как хранить словарь в наборе данных HDF5
У меня есть словарь, где ключ - это объект datetime, а значение - набор целых чисел:
>>> d.items()[0]
(datetime.datetime(2012, 4, 5, 23, 30), (14, 1014, 6, 3, 0))
Я хочу сохранить его в наборе данных HDF5, но если я попытаюсь просто сбросить словарь, h5py вызывает ошибку:
TypeError: объект dtype dtype ('object') не имеет собственного эквивалента HDF5
Что было бы "лучшим" способом преобразования этого словаря, чтобы я мог хранить его в наборе данных HDF5?
В частности, я не хочу просто дублировать словарь в массиве numpy, так как это усложнит поиск данных на основе запроса datetime.
Ответы
Ответ 1
Я нашел два способа:
I) преобразовать объект datetime в строку и использовать его в качестве имени набора данных
h = h5py.File('myfile.hdf5')
for k, v in d.items():
h.create_dataset(k.strftime('%Y-%m-%dT%H:%M:%SZ'), data=np.array(v, dtype=np.int8))
к которым можно получить доступ к данным путем ввода ключевых строк (имя набора данных). Например:
for ds in h.keys():
if '2012-04' in ds:
print(h[ds].value)
II) преобразовать объект datetime в подгруппы данных
h = h5py.File('myfile.hdf5')
for k, v in d.items():
h.create_dataset(k.strftime('%Y/%m/%d/%H:%M'), data=np.array(v, dtype=np.int8))
обратите внимание на косые черты в строке strftime, которая создаст соответствующие подгруппы в файле HDF. Доступ к данным можно получить напрямую, как h['2012']['04']['05']['23:30'].value
, или путем итерации с предоставленными итераторами h5py или даже с помощью пользовательских функций через visititems()
Для простоты я выбираю первый вариант.
Ответ 2
Я бы сериализовал объект в JSON или YAML и сохранил полученную строку как атрибут в соответствующем объекте (группа HDF5 или набор данных).
Я не уверен, почему вы используете дату-время как имя набора данных, однако, если вам абсолютно не нужно искать ваш набор данных напрямую с помощью datetime.
p.s. Для чего это стоит, PyTables намного проще в использовании, чем низкоуровневый h5py.
Ответ 3
В настоящее время у нас есть глубокий (www.deepdish.io):
import deepdish as dd
dd.io.save(filename, {'dict1': dict1, 'dict2': dict2}, compression=('blosc', 9))
Ответ 4
Этот вопрос относится к более общему вопросу о возможности хранения любого типа словаря в формате HDF5
. Сначала преобразуйте словарь в строку. Затем, чтобы восстановить словарь, используйте библиотеку ast
, используя команду import ast
. В следующем примере приведен пример.
>>> d = {1:"a",2:"b"}
>>> s = str(d)
>>> s
"{1: 'a', 2: 'b'}"
>>> ast.literal_eval(s)
{1: 'a', 2: 'b'}
>>> type(ast.literal_eval(s))
<type 'dict'>