1. 程式人生 > >Python資料儲存與壓縮

Python資料儲存與壓縮

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