Python資料儲存與壓縮
阿新 • • 發佈:2019-01-09
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
。