一篇很短的小短文,主要推荐下作科学计算是大量数据的储存问题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分钟也能够来一篇小博客……看来之后得勤奋点才行了……