Python pickle文件奇怪的大

时间:2014-08-06 11:31:54

标签: python pickle

我制作了一个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)

如果您发现我的计算或代码出现问题,请告诉我们!

1 个答案:

答案 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,所以我不会试图说服你进一步不存储对象,但要注意存储对象的开销。

作为选项:减少训练数据的大小/选择较少的对象。