【问题标题】:Accessing HDF5 key-value store using integer keys使用整数键访问 HDF5 键值存储
【发布时间】:2021-11-11 11:22:01
【问题描述】:

我正在尝试使用 HDF5 作为后端在 python 中编写键值存储。理想情况下,我希望商店表现得像一个 python 字典。我当前的代码现在看起来像这样

from multimethod import multimethod
from typing import List
import h5py

class FancyDic(MutableMapping):

def __init__(self, fname):
    self.fname = fname
    self.__store__ = h5py.File(fname,'w')
    

def get_dic(self, df):
    data_dict = dict()
    for col in df.columns:
        if "coord" in col:
            pass
        else:
            data_dict[col] = df[col].values
    return data_dict

@multimethod
def update(self:object, path:str, key:str, value:float):
    self.__store__[path + key] = value
    
@update.register
def _(self:object, path:str, key:str, value:np.ndarray):
    self.__store__[path + key] = value
    

@update.register
def _(self:object, path:str, key:str, value:list):
    self.__store__[path + key] = np.asarray(value) 
    
    
    
@update.register
def _(self:object, path:str, key:str, value:str):
    self.__store__.attrs[path+key] = value
    
    
@update.register
def _(self:object, path:str, key:str, value:List[str]):
    self.__store__[path + key] = np.array(value).astype('|S100')
    
    

@update.register
def _(self:object, path:str, key:str, value:dict):
    for key, item in value.items():
        key = str(key)
        if isinstance(item, pandas.core.frame.DataFrame):
            data_dic = self.get_dic(item)
            self.update(path+"/"+key,"/",data_dic )
        else:
       
            self.update(path+"/"+key,"/",item )
            

def __openfile__(self, fname):
    self.__store__ =  h5py.File(fname,'r+')

def closefile(self):
    self.__store__.close()


# The next five methods are requirements of the ABC.
def __setitem__(self,path, key, value):
    self.update(path, key, value)
    
def __getitem__(self, key):
    if isinstance(key, int):
        key = str(key)
    return self.__store__[key]


def __delitem__(self, key):
    del self.__dict__[key]
def __iter__(self):
    return iter(self.__dict__)
def __len__(self):
    return len(self.__dict__)
# The final two methods aren't required, but nice for demo purposes:
def __str__(self):
    '''returns simple dict representation of the mapping'''
    return str(self.__dict__)

当我尝试访问一个元素时,它可以工作,例如我可以做FancyDicObj[key] 等,但是当我这样做时,它会按预期返回一个 HDF5 组对象,我只能通过字符串键访问它。我也希望能够通过整数键访问元素。有没有办法引入一个函数,以便在这个键值存储中仍然可以通过整数键进行下标访问。例如 FancyDicObj[key][1] 而不是 FancyDicObj[key]["1"] 即使我将数据存储在数字键的字符串表示形式中。

【问题讨论】:

  • 如果要对字典使用整数键,则需要使用整数创建。为什么你更喜欢整数而不是字符串?你想做什么?为什么不使用FancyDicObj[key][str(1)] 来获取整数值的字符串?
  • 因为它有点难看,而且这与 python 字典语法不兼容,我可以只使用整数键而不强制转换为字符串我的问题是我可以将花哨的 dicobj 包装在另一个类中并只使用整数像我使用 python 字典一样的键
  • 因为 rifht 现在在第一级访问,我可以通过整数键访问,因为该类将整数键转换为字符串,而无需我告诉它在 hdf5 文件的较低嵌套级别它没有完成访问 fancydicobj 会返回没有整数键访问的组或数据集

标签: python hdf5 h5py key-value-store


【解决方案1】:

这很难看,因为您试图将方形钉子推入圆孔中。 HDF5 是结构化数据的容器(用户在其中定义结构;也称为模式)。组用于组织数据,数据集可以保存典型的 Python 标量(整数、浮点数、字符串)和类似对象的 NumPy 数组。 但是,HDF5 没有字典对象。因此,如果您想存储 Python 字典,则必须将数据映射到 HDF5 对象:组、数据集和属性。

您是否考虑过使用 pickle 模块来执行此操作?以下是关于此的 2 个 SO 主题:

如果您决定继续使用 HDF5:
在您的class FancyDic() 中,您将字典键映射到组名。名称是字符串。无法解决此限制。

HDF5 中的属性提供了一种替代机制。它们旨在保存少量数据并使用name=value 对(类似于字典)。但是,出于性能原因,它们应该很小(

【讨论】:

  • 当然这是真的,我知道如何将字典保存到 pickle 文件中,我只是想知道是否有一种方法可以在 hdf5 中执行我想要的操作。我知道它没有字典对象,但我正在尝试使用 hdf5 作为后端编写一个键值存储,它可以访问整数键。对于我知道的属性,我用它来存储小数据我的问题更多是关于编程,如果有办法包装 hdf5 文件以允许整数键
猜你喜欢
  • 2016-10-19
  • 2020-08-19
  • 2017-01-21
  • 2016-07-29
  • 2022-01-21
  • 2013-08-08
  • 2011-10-10
  • 1970-01-01
  • 2010-10-29
相关资源
最近更新 更多