2012-10-11 16 views
6

Tôi đã một đối tượng ngâm trong một file có tên b1.pkl:Tại sao tải python pickle và dump thổi phồng kích thước của một đối tượng trên đĩa?

$ ls -l b* 
-rw-r--r-- 1 fireball staff 64743950 Oct 11 15:32 b1.pkl 

Sau đó, tôi chạy mã python sau để tải các đối tượng và đổ nó vào một tập tin mới:

import numpy as np 
import cPickle as pkl 

fin = open('b1.pkl', 'r') 
fout = open('b2.pkl', 'w') 

x = pkl.load(fin) 
pkl.dump(x, fout) 

fin.close() 
fout.close() 

Các tập tin mã này tạo ra lớn gấp hai lần:

$ ls -l b* 
-rw-r--r-- 1 fireball staff 64743950 Oct 11 15:32 b1.pkl 
-rw-r--r-- 1 fireball staff 191763914 Oct 11 15:47 b2.pkl 

Có thể giải thích tại sao tệp mới lớn hơn tệp gốc không? Nó phải chứa chính xác cấu trúc tương tự.

+3

là dưa chua ban đầu được tạo nên bằng cách sử dụng cùng một giao thức? – root

Trả lời

10

Có thể là dưa chua ban đầu đã sử dụng một số giao thức khác. Ví dụ: thử chỉ định protocol=2 làm đối số từ khóa cho số pickle.dump thứ hai và kiểm tra lại. Binary pickle nên có kích thước nhỏ hơn nhiều.

+0

Tôi đã thử chỉ định giao thức = 2 và, thì, tệp kết quả có cùng kích thước với tệp gốc! – user1389890

+0

thì tốt lắm :) – root

3

pkl.dump (x, fout, 2) có thể dẫn đến cùng một kích thước. Không chỉ định phiên bản giao thức sẽ làm cho dưa chua sử dụng phiên bản cũ 0.

4

Rất có thể b1.pkl ban đầu của bạn đã được chọn bằng cách sử dụng chế độ giao thức hiệu quả hơn (1 hoặc 2). Vì vậy, tệp của bạn bắt đầu nhỏ hơn.

Khi bạn tải bằng cPickle, nó sẽ tự động phát hiện giao thức cho bạn từ tệp. Nhưng khi bạn đi và đổ nó ra một lần nữa với mặc định args, nó sẽ sử dụng giao thức 0 đó là lớn hơn nhiều. Nó làm điều này cho tính di động/khả năng tương thích. Bạn được yêu cầu yêu cầu rõ ràng giao thức nhị phân.

import numpy as np 
import cPickle 

# random data 
s = {} 
for i in xrange(5000): 
    s[i] = np.random.randn(5,5) 

# pickle it out the first time with binary protocol 
with open('data.pkl', 'wb') as f: 
    cPickle.dump(s, f, 2) 

# read it back in and pickle it out with default args 
with open('data.pkl', 'rb') as f: 
    with open('data2.pkl', 'wb') as o: 
     s = cPickle.load(f) 
     cPickle.dump(s, o) 

$ ls -l 
1174109 Oct 11 16:05 data.pkl 
3243157 Oct 11 16:08 data2.pkl 
+0

Khi tôi bán hết bản gốc, tôi đã sử dụng thông số pickle là -1. Rõ ràng, nó dẫn đến một đại diện nhỏ gọn hơn trên đĩa. Tôi đoán nó phải đã gây ra python để sử dụng giao thức = 2. – user1389890

Các vấn đề liên quan