我制作了一个pickle文件,将每个像素的灰度值存储在100,000个80x80大小的图像中。
(加上一组100,000个整数,其值为一位数)。
我对泡菜总大小的近似值是,
4 byte x 80 x 80 x 100000 = 2.88 GB
加上整数数组,它不应该那么大。
然而,生成的pickle文件超过了16GB,因此只需花费数小时来取消它并加载它,并且它在获取完全内存资源后最终冻结。
我的计算有问题,还是我腌制它的方式?
我用以下方式腌制文件。
from PIL import Image
import pickle
import os
import numpy
import time
trainpixels = numpy.empty([80000,6400])
trainlabels = numpy.empty(80000)
validpixels = numpy.empty([10000,6400])
validlabels = numpy.empty(10000)
testpixels = numpy.empty([10408,6400])
testlabels = numpy.empty(10408)
i=0
tr=0
va=0
te=0
for (root, dirs, filenames) in os.walk(indir1):
print 'hello'
for f in filenames:
try:
im = Image.open(os.path.join(root,f))
Imv=im.load()
x,y=im.size
pixelv = numpy.empty(6400)
ind=0
for ii in range(x):
for j in range(y):
temp=float(Imv[j,ii])
temp=float(temp/255.0)
pixelv[ind]=temp
ind+=1
if i<40000:
trainpixels[tr]=pixelv
tr+=1
elif i<45000:
validpixels[va]=pixelv
va+=1
else:
testpixels[te]=pixelv
te+=1
print str(i)+'\t'+str(f)
i+=1
except IOError:
continue
trainimage=(trainpixels,trainlabels)
validimage=(validpixels,validlabels)
testimage=(testpixels,testlabels)
output=open('data.pkl','wb')
pickle.dump(trainimage,output)
pickle.dump(validimage,output)
pickle.dump(testimage,output)
如果您发现我的计算或代码出现问题,请告诉我们!
答案 0 :(得分:2)
Python Pickles不是一种节省数据的机制,因为你在存储对象而不是“只是数据”。
以下测试用例在我的系统上占用24kb,这是一个存储在pickle
中的小型,人口稀少的numpy数组:
import os
import sys
import numpy
import pickle
testlabels = numpy.empty(1000)
testlabels[0] = 1
testlabels[99] = 0
test_labels_size = sys.getsizeof(testlabels) #80
output = open('/tmp/pickle', 'wb')
test_labels_pickle = pickle.dump(testlabels, output)
print os.path.getsize('/tmp/pickle')
此外,我不确定为什么你认为4kb是Python中数字的大小 - 非numpy int是24字节(sys.getsizeof(1)
)和numpy
数组是最小的80字节(sys.getsizeof(numpy.array([0], float))
)。
正如你所说的对我评论的回应,你有理由留在Pickle,所以我不会试图说服你进一步不存储对象,但要注意存储对象的开销。
作为选项:减少训练数据的大小/选择较少的对象。