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

时间:2016-08-24 13:39:21

标签: python hdf5

我有一个这样的课程:

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

我需要创建数百万个这些对象。 id是一个整数以及user_id,但是photo是一个大小为64的bool数组。我的老板要我将所有这些存储在hdf5文件中。我还需要能够根据其user_id属性进行查询,以获得具有相同user_id的所有照片。首先,我如何存储它们?甚至可以吗?其次,一旦我存储(如果我可以)他们如何查询它们?谢谢。

1 个答案:

答案 0 :(得分:3)

虽然您可以将整个数据结构存储在单个HDF5表中,但将所描述的类存储为三个单独的变量(两个一维整数数组和一个用于存储“照片”属性的数据结构)可能要容易得多。 / p>

如果您关心文件大小和速度而不关心文件的人类可读性,您可以将64个bool值建模为UINT8的8个1D阵列或UINT8(或CHAR)的2个阵列N x 8 。然后,您可以实现一个简单的接口,将您的bool值打包到UINT8的位中并返回(例如,How to convert a boolean array to an int array

据我们所知,HDF5中没有内置搜索功能,但您可以读取包含user_ids的变量,然后只需使用Python查找与user_id匹配的所有元素的索引

获得索引后,您可以读入其他变量的相关切片。 HDF5原生支持高效切片,但它适用于范围,因此您可能想要考虑如何在连续块中存储具有相同user_id的记录,请参阅此处的讨论

h5py: Correct way to slice array datasets

您可能还想查看pytables - 一个python interace,它构建在hdf5上,用于将数据存储在类似表格的结构中。

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