30

我有一本字典,其中键是日期时间对象,值是整数元组:

>>> d.items()[0]
(datetime.datetime(2012, 4, 5, 23, 30), (14, 1014, 6, 3, 0))

我想将它存储在 HDF5 数据集中,但如果我尝试只转储字典 h5py 会引发错误:

TypeError: Object dtype dtype('object') has no native HDF5 equivalent

转换此字典以便我可以将其存储在 HDF5 数据集中的“最佳”方法是什么?

具体来说,我不想只是将字典转储到 numpy 数组中,因为它会使基于日期时间查询的数据检索复杂化。

4

5 回答 5

16

我找到了两种方法:

I)将日期时间对象转换为字符串并将其用作数据集名称

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)将日期时间对象转换为数据集子组

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()

为简单起见,我选择第一个选项。

于 2013-05-11T09:31:17.740 回答
13

这个问题与能够以HDF5格式存储任何类型的字典的更一般的问题有关。首先,将字典转换为字符串。然后要恢复字典,请使用命令使用astimport 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'>
于 2018-01-04T18:54:57.313 回答
7

以前的答案旨在将 Python 字典存储为 hdf5 数据集。以下代码可用于将 Python 字典存储为 hdf5 属性(元数据),这是一种更合乎逻辑的方法:

import h5py
import numpy as np

#Writing data
d1 = np.random.random(size = (1000,20))  #sample data
hf = h5py.File('test_data.h5', 'w')
dset1=hf.create_dataset('dataset_1', data=d1)
#set some metadata directly
hf.attrs['metadata1']=5

#sample dictionary object
sample_dict={"metadata2":1, "metadata3":2, "metadata4":"blah_blah"}

#Store this dictionary object as hdf5 metadata
for k in sample_dict.keys():
    hf.attrs[k]=sample_dict[k]

hf.close()

#Reading data
hf1 = h5py.File('test_data.h5', 'r')
for name in hf1:
    print(name)

print(hf1.attrs.keys())
hf1.close()

这给出了一个输出

dataset_1
<KeysViewHDF5 ['metadata1', 'metadata2', 'metadata3', 'metadata4']>

这意味着直接分配为属性的元数据1和从字典对象获得的元数据2、3、4同时作为属性存储。

于 2020-08-13T06:17:18.330 回答
6

我会将对象序列化为 JSON 或 YAML,并将生成的字符串作为属性存储在适当的对象(HDF5 组或数据集)中。

但是,我不确定您为什么使用日期时间作为数据集名称,除非您绝对需要直接按日期时间查找数据集。

ps 对于它的价值,PyTables 比低级 h5py 更容易使用

于 2013-12-20T17:56:09.743 回答
5

现在我们有 deepdish (www.deepdish.io):

import deepdish as dd
dd.io.save(filename, {'dict1': dict1, 'dict2': dict2}, compression=('blosc', 9))
于 2017-11-07T23:36:58.063 回答