Python 我可以将自己的类对象存储到hdf5中吗?

Python 我可以将自己的类对象存储到hdf5中吗?,python,hdf5,Python,Hdf5,我有一门课是这样的: class C: def __init__(self, id, user_id, photo): self.id = id self.user_id = user_id self.photo = photo 我需要创建数百万个这样的对象。id是一个整数以及用户id,但photo是一个大小为64的布尔数组。我的老板想让我把它们都存储在hdf5文件中。我还需要能够根据他们的用户id属性进行查询,以获得所有具有相同

我有一门课是这样的:

class C:
     def __init__(self, id, user_id, photo):
         self.id = id
         self.user_id = user_id
         self.photo = photo

我需要创建数百万个这样的对象。id是一个整数以及用户id,但photo是一个大小为64的布尔数组。我的老板想让我把它们都存储在hdf5文件中。我还需要能够根据他们的用户id属性进行查询,以获得所有具有相同用户id的照片。首先,我如何存储它们?我甚至可以?第二,一旦我存储了它们(如果可以的话),我如何查询它们?谢谢。

尽管您可以将整个数据结构存储在一个HDF5表中,但将所描述的类存储为三个单独的变量可能要容易得多——两个1D整数数组和一个用于存储“photo”属性的数据结构

如果您关心文件大小和速度,而不关心文件的可读性,则可以将64 bool值建模为UINT8的8 1D数组或UINT8的2 d数组N x 8(或字符)。然后,您可以实现一个简单的接口,将bool值打包成UINT8位并返回(例如)

据我们所知,HDF5中没有内置的搜索函数,但是您可以读入包含
用户id
的变量,然后简单地使用Python查找与
用户id
匹配的所有元素的索引

一旦有了索引,就可以读入其他变量的相关部分。HDF5本机支持高效切片,但它在范围上工作,因此您可能想考虑如何将具有相同
用户id的记录存储在连续块中,请参阅此处的讨论

您可能还想研究pytables——一种python交互,它构建在hdf5之上,用于将数据存储在类似structures的表中

import numpy as np
import h5py


class C:
    def __init__(self, id, user_id, photo):
        self.id = id
        self.user_id = user_id
        self.photo = photo

def write_records(records, file_out):

    f = h5py.File(file_out, "w")

    dset_id = f.create_dataset("id", (1000000,), dtype='i')
    dset_user_id = f.create_dataset("user_id", (1000000,), dtype='i')
    dset_photo = f.create_dataset("photo", (1000000,8), dtype='u8')
    dset_id[0:len(records)] = [r.id for r in records]
    dset_user_id[0:len(records)] = [r.user_id for r in records]
    dset_photo[0:len(records)] = [np.packbits(np.array(r.photo, dtype='bool').astype(int)) for r in records]
    f.close()

def read_records_by_id(file_in, record_id):
    f = h5py.File(file_in, "r")
    dset_id = f["id"]
    data = dset_id[0:2]
    res = []
    for idx in np.where(data == record_id)[0]:
        record = C(f["id"][idx:idx+1][0], f["user_id"][idx:idx+1][0], np.unpackbits( np.array(f["photo"][idx:idx+1][0],  dtype='uint8') ).astype(bool))
        res.append(record)
    return res 

m = [ True, False,  True,  True, False,  True,  True,  True]
m = m+m+m+m+m+m+m+m
records = [C(1, 3, m), C(34, 53, m)]

# Write records to file
write_records(records, "mytestfile.h5")

# Read record from file
res = read_records_by_id("mytestfile.h5", 34)

print res[0].id
print res[0].user_id
print res[0].photo

非常感谢你的帮助。虽然您提供的信息非常重要,但由于我们将要进行的编写操作,我无法将数据存储在连续的块中。我想我将不得不使用mongodb进行存储。您应该尝试填充一个HDF5文件,看看性能是否可以接受。对于您的数据类型,使用mongo可能确实有意义,只需记住在单个集合中可以存储的数据有16MB的上限。@Maksym我有类似的用例,但在photo属性中我有numpy ndarray形状(1024,768,3),这是可变的,我关心速度和时间,但不关心可读性,您有什么建议?@避免受读取时间、写入时间或查询时间的限制?如果您有大量数据的恒定流,那么研究parquet()或其他支持流的格式可能是有意义的。另外,只要您的shape(1024、768、3)数组的类型与user_id和其他属性相同,您就可以将完整的记录存储为平面1D数组,并在读取时重新整形。另外,为了更正我前面的评论,Mongo中的16MB cap在集合中的单个记录上,而不是集合本身。