Python数据存储与压缩
跑实验要用到数据集,对于一些不大的数据集,为了节省时间,有时候会先预处理,然后将各个文件存储成一个大文件,一次性读入内存,省去了每个迭代重新读入和重新预处理的时间。这里讨论一些数据存储与压缩方式,至于Tensorflow里用到的Dataset之类的数据存取不在本文范围内。
本文主要针对以下几点进行对比分析:多Tensor存储的支持性、占用空间大小、读取方便性。
Python常用数据存储与压缩方式
1. numpy.save / numpy.savez
利用np.save(file, obj)
将单个Tensor保存为.npy
文件,利用np.save(file, **obj)
将多个Tensor以字典的形式存储为.npz
文件,可实现多Tensor存储。
2. h5py
利用h5py.create_dataset
将多个Tensor存入同一个.h5
文件,可实现多Tensor存储。
3. cPickle
利用cPickle.dump
将任意结构存入.pkl
文件,可实现多Tensor存储。
存储与读取
用以下随机数据为例,给出存储和读取的代码。
X = np.random.normal(size=(100,100,100))
Y = np.random.normal(size=(100,100,100))
1. 存储
'''np.savez'''
data = {'X':X, 'Y':Y}
np.savez("test/data.npz", **data)
'''np.save'''
np.save("test/data_X.npy", X)
np.save("test/data_Y.npy", Y)
'''h5py'''
with h5py.File('test/data.h5', 'w') as f:
f.create_dataset('X', data=X)
f.create_dataset('Y', data=Y)
'''cPickle'''
with open('test/data.pkl', 'w') as f:
cPickle.dump(data, f)
2. 读取
'''from .npz'''
data = np.load("test/data.npz")
X, Y = data['X'], data['Y']
print X.shape, type(X)
print Y.shape, type(Y)
'''from .npy'''
X = np.load("test/data_X.npy")
Y = np.load("test/data_Y.npy")
print X.shape, type(X)
print Y.shape, type(Y)
'''from .h5'''
with h5py.File("test/data.h5", "r") as f:
X = f["X"][:]
Y = f["Y"][:]
print X.shape, type(X)
print Y.shape, type(Y)
'''from cPickle'''
with open("test/data.pkl", "r") as f:
data = cPickle.load(f)
X, Y = data['X'], data['Y']
print X.shape, type(X)
print Y.shape, type(Y)
方法对比
存储便捷性
多Tensor存储 | 存储便捷性 | |
---|---|---|
np.savez | 支持 | 方便,以字典形式一次性存入 |
np.save | 支持 | 不方便,逐个npy存储,还要tar打包 |
h5py | 支持 | 较方便,要逐个分多次存入,注意h5py不能存入字典 |
cPickle | 支持 | 方便,任意类型一次性存入 |
占用空间
占用空间 | gzip后 | zip后 | |
---|---|---|---|
np.savez | 16000450 / 16M | 15356970 / 15M | 15357108 / 15M |
np.save | 16000356 / 16M | 15357071 / 15M | 15357254 / 15M |
h5py | 16002144 / 16M | 15356430 / 15M | 15356568 / 15M |
cPickle | 47382990 / 46M | 21007058 / 21M | 21007197 / 21M |
读取
读取便捷性 | |
---|---|
np.savez | 方便,需注意所有存入的数据被强制转换为ndarray |
np.save | 不方便,逐个npy分别读取 |
h5py | 方便,需注意所有存入的数据被封装为dataset |
cPickle | 方便,读入后就是原类型 |
总结
np.savez
在所需存储数据全是ndarray
类型时,各个方面都表现优秀;h5py
可存储字典外的任意类型,有这方面的需要时可选用;cPickle
虽然可存储任意类型,但其占用的空间和存取消耗的时间都明显大于其他方法,比不上h5py
,如果一定要存字典,不如单独存成json
。