【问题标题】:How to store and load a Python dictionary with HDF5如何使用 HDF5 存储和加载 Python 字典
【发布时间】:2020-07-28 07:22:30
【问题描述】:

我在从 HDF5 文件加载字典(字符串键和数组/列表值)时遇到问题(我认为存储工作正常 - 正在创建一个文件并包含数据)。我收到以下错误:

ValueError: malformed node or string:

我的代码是:

import h5py

def store_table(self, filename):
    table = dict()
    table['test'] = list(np.zeros(7,dtype=int))

    with h5py.File(filename, "w") as file:
        file.create_dataset('dataset_1', data=str(table))
        file.close()


def load_table(self, filename):
    file = h5py.File(filename, "r")
    data = file.get('dataset_1')
    print(ast.literal_eval(data))

我已经使用 ast 方法在线阅读 literal_eval 应该可以工作,但它似乎没有帮助...我如何“解压”HDF5 所以它是又是一本字典?

任何想法都将不胜感激。

【问题讨论】:

  • 您考虑过创建属性吗?每个属性名==键名和属性值==键值。这样您就可以避免处理不同值数据类型的问题。 (例如一个值是字符串,一个是整数等)。

标签: python dictionary hdf5 h5py


【解决方案1】:

如果我理解你想要做什么,这应该有效:

import numpy as np
import ast
import h5py


def store_table(filename):
    table = dict()
    table['test'] = list(np.zeros(7,dtype=int))

    with h5py.File(filename, "w") as file:
        file.create_dataset('dataset_1', data=str(table))


def load_table(filename):
    file = h5py.File(filename, "r")
    data = file.get('dataset_1')[...].tolist()
    file.close();
    return ast.literal_eval(data)

filename = "file.h5"
store_table(filename)
data = load_table(filename)
print(data)

【讨论】:

  • 感谢您的回复,但我想存储一个字典(字符串键和数组/列表值)。
  • 我不确定您为什么要这样做,但我相应地更新了我的代码。通常,您会将键和值存储在不同的数据集中(在同一个文件中)。
  • 太棒了,这行得通!我不知道键和值应该分开存储——这是为什么呢?检索字典时如何再次组合它们?谢谢!
  • 我所说的键是“测试”,“键”是数据集的名称(在您的示例中为“dataset_1”)。将它们分开存储是明智的,最简单的方法是构造两个 Numpy 数组:一个是字典键,另一个是字典值。
  • @MROB 你忘了在第二个函数中关闭文件,在第一个函数中关闭了两次!
【解决方案2】:

我不清楚你真正想要完成什么。 (我怀疑你的字典有七个以上的零。否则,HDF5 存储你的数据是多余的。)如果你有很多非常大的字典,最好将数据转换为 NumPy 数组,然后 1)创建和使用data= 加载数据集或2)使用适当的dtype 创建数据集,然后填充。您可以创建具有混合数据类型的数据集,这在之前的解决方案中没有解决。如果这些情况不适用,您可能希望将字典保存为属性。属性可以与组、数据集或文件对象本身相关联。哪个最好取决于您的要求。

我写了一个简短的例子来展示如何加载字典键/值对作为标记到组的属性名称/值对。对于这个例子,我假设字典有一个名称键和组名进行关联。对于数据集或文件对象,该过程几乎相同(只需更改对象引用)。

import h5py

def load_dict_to_attr(h5f, thisdict) :

   if 'name' not in thisdict:
       print('Dictionary missing name key. Skipping function.')
       return

   dname = thisdict.get('name') 
   if dname in h5f:
       print('Group:' + dname + ' exists. Skipping function.')
       return
   else: 
       grp = h5f.create_group(dname)

       for key, val in thisdict.items():
           grp.attrs[key] = val

###########################################

def get_grp_attrs(name, node) :

    grp_dict = {}
    for k in node.attrs.keys():
        grp_dict[k]= node.attrs[k]

    print (grp_dict)

###########################################

car1 = dict( name='my_car', brand='Ford', model='Mustang', year=1964,
             engine='V6',  disp=260,  units='cu.in' )
car2 = dict( name='your_car', brand='Chevy', model='Camaro', year=1969,
             engine='I6',  disp=250,  units='cu.in' )
car3 = dict( name='dads_car', brand='Mercedes', model='350SL', year=1972,
             engine='V8',  disp=4520, units='cc' )
car4 = dict( name='moms_car', brand='Plymouth', model='Voyager', year=1989,
             engine='V6',  disp=289,  units='cu.in' )

a_truck = dict(             brand='Dodge', model='RAM', year=1984,
               engine='V8', disp=359, units='cu.in' )

garage = dict(my_car=car1, 
              your_car=car2,
              dads_car=car3,
              moms_car=car4,
              a_truck=a_truck )

with h5py.File('SO_61226773.h5','w') as h5w:

    for car in garage:
        print ('\nLoading dictionary:', car)
        load_dict_to_attr(h5w, garage.get(car))

with h5py.File('SO_61226773.h5','r') as h5r:

    print ('\nReading dictionaries from Group attributes:')
    h5r.visititems (get_grp_attrs)

【讨论】:

    猜你喜欢
    • 2013-05-05
    • 2017-09-28
    • 1970-01-01
    • 2021-05-12
    • 1970-01-01
    • 2011-10-29
    • 2015-11-23
    • 2016-02-21
    • 2015-01-28
    相关资源
    最近更新 更多