h5py 批量存储数据

  Posted by Mr.Zhang on 19 Jun, 2019

   PYTHON   

最近做个数据处理任务,50万条数据,独热编码6000维,numpyuint8勉强内存里能跑,硬盘缓存大的惊人,想用批量处理,批量硬盘读写的方法来做,管理比较麻烦。用mxnet做批数据迭代,发现支持HDF5格式,查一查果然好东西,而且这本来就是设计用来做数据分析用的。

使用h5py可以轻易的创建和读取h5格式文件,两个主要概念groupdataset对应于常用的文件夹和数据库,下面示例是如何批量追加到文件中,避免内存溢出。

import numpy as np
import h5py
def save_h5(h5f,data,target):
    shape_list=list(data.shape)
    # 如果不存在目标数据集,则创建
    if not h5f.__contains__(target):
        shape_list[0]=None
        dataset = h5f.create_dataset(target,
                                     data=data,
                                     maxshape=tuple(shape_list), 
                                     chunks=True)
        return
    else:
        dataset = h5f[target]
    len_old=dataset.shape[0]
    len_new=len_old+data.shape[0]
    shape_list[0]=len_new
    dataset.resize(tuple(shape_list))
    dataset[len_old:len_new] = data

file_name='D:/logs/data_onehot.h5'
h5f=h5py.File(file_name)

# 创建group,类似于文件夹
h5f.create_group('subgroup')
# subgroup.create_dataset('sub_dataset', data=x)

# 下列为批量存入方法
i = 0
X = []
y = []
for k,v in u2t.items():
    y.append(k)
    X.append(list2hot(v))
    i += 1
    if i % 1000 == 0:
        save_h5(h5f,data=np.array(X),target='data_onehot')
        save_h5(h5f,data=np.array(y),target='data_uid')
        logger.info('批次' + str(i) + '存入h5文件')
        X = []
        y = []
# 下面两行是保证最后批次内数据存入
save_h5(h5f,data=np.array(X),target='data_onehot')
save_h5(h5f,data=np.array(y),target='data_uid')

# 列出所有数据集
list(h5f.keys())
# 类似于字典的操作方法,包含itor
dset = h5f['data_onehot']
dset.name
dset.shape
dset.dtype
# 可以添加属性
dset.attrs['name'] = 'user'
# 可以切片
dset[0:5:2]
# 记得关闭
h5f.close()