一篇很短的小短文,主要推薦下作科學計算是大量數據的儲存問題html
最近在作一個CNN的項目,文件夾裏有20w張圖片要讀入並保存到一個data文件(否則每次都讀20w文件太麻煩)。python
折騰了一個下午,發現了一個極好用的包 h5py:將數據儲存在hdf5文件中。linux
這東西有多好用呢?ubuntu
速度,內存佔用,壓縮程度都比cPickle+gzip來的優秀。python2.7
相比之下上面兩個變逗比了……性能
我把全部圖片都放在一個ndarray並保存爲一個文件:大數據
8190張圖片的.mat 16GB, 81900圖片的.pkl.gz……根本就生成不了, 81900張圖片的.h5 15GB.網站
不只能夠保存大數據,並且壓縮率是mat的十倍!ui
可見爲何我這麼興奮來一發……spa
一、numpy.save , numpy.savez , scipy.io.savemat
numpy和scipy提供的數據存儲方法。官方說savez是save的壓縮版,儘管在實踐中,什麼都沒能壓縮到。
並且這三個方法產生的文件大小都是同樣的…………很是大。
8000張256*256*3的圖片出來就是一個16G的文件,簡直忍無可忍。並且調用方法很麻煩。
二、cPickle + gzip
這裏忽略pickle這傢伙,直接被cPiclke虐了。
.pkl.gz 是mnist的官方後綴。看來是會很好用的樣子。
可是實際使用中,有兩個難以免的問題:
前者我就不說了。關於後者,這是python官bug,若是你在cPickle.dump()的時候碰上「 SystemError: error return without exception set」,那麼恭喜你,中獎了。
python官方對於這個問題的解釋:http://bugs.python.org/issue11564
咦?修好了?毛線! 3修好了,2.7照樣bug,因此若是你的linux或者ubuntu內嵌的是python2.7,哭死吧。
儘管cPickle+gzip性能已經很優秀,可是和h5py性能的對比,看這篇:
http://www.shocksolution.com/2010/01/storing-large-numpy-arrays-on-disk-python-pickle-vs-hdf5adsf/
三、h5py
抱歉找不到缺點,惟一的缺點就是很難安裝。因此一下是h5py安裝教程。
官方教程:http://docs.h5py.org/en/latest/build.html#install
這裏教教你,官方教程都是坑爹的:沒有源叫你apt-get,給你bin讓你make。因此這裏, 我走過能行的路:
一、肯定系統有python,numpy,libhdf5-serial-dev,和HDF5.前三者通常都有。這裏要安裝HDF5
二、去HDF5官方網站下載編譯好的bin(是的,儘管教程讓編譯,這裏給用戶的就是編譯好的bin,搞得我這小白編譯了半天);
http://www.hdfgroup.org/HDF5/
三、解壓,重命名文件夾爲hdf5,移動到 /usr/local/hdf5 下
四、添加環境變量:
export HDF5_DIR=/usr/local/hdf5
到這裏HDF5就安裝好了,只有安裝好的HDF5才能順利安裝h5py
五、pip install h5py
寫入:import h5pyimport numpy as np
data = mp.array( [222,333,444] )
label = np.array( [0,1,0] )
img_num = np.array( [0,1,2] )
# 建立HDF5文件
file = h5py.File('TrainSet_rotate.h5','w')
# 寫入 file.create_dataset('train_set_x', data = data) file.create_dataset('train_set_y', data = label) file.create_dataset('train_set_num',data = img_num) # 。。。。。。。。。
file.close()
讀取:
import numpy as np import h5py # 讀方式打開文件 file=h5py.File('TrainSet_rotate.h5','r') # 儘管後面有 '[:]', 可是矩陣怎麼進去的就是怎麼出來的,不會被拉長(matlab後遺症) train_set_data = file['train_set_x'][:] train_set_y = file['train_set_y'][:] train_set_img_num = file['train_set_img_num'][:] # ......... file.close()
好了,你已經會使用h5py了,快嘗試下h5py給你帶來的快感吧!
附送小技巧:如何在同一行輸出
一、
for i in range(10): print("Loading" + "." * i) sys.stdout.write("\033[F") # Cursor up one line
二、
for x in range (0,5): b = "Loading" + "." * x print (b, end="\r")
前面的方法會好用點
原來20分鐘也能夠來一篇小博客……看來之後得勤奮點才行了……