2015-11-22 34 views
5

Próbuję pracować z CIFAR-10 dataset, która zawiera a special version for python.Jak odczytywać serializowane dane przez python2 cPikle z piklem python3?

Jest zbiorem plików binarnych, z których każdy reprezentuje słownik macierzy o rozmiarze 10k. Pliki zostały oczywiście utworzone przez python2 cPickle.

Próbowałem załadować go z python2 następująco:

import cPickle 
with open("data/data_batch_1", "rb") as f: 
    data = cPickle.load(f) 

Działa to naprawdę świetnie. Jednak, gdy próbuję załadować dane z python3 (nie cPickle ale pickle ma zamiast), to nie:

import pickle 
with open("data/data_batch_1", "rb") as f: 
    data = pickle.load(f) 

Jeśli nie powiedzie się z powodu następującego błędu:

UnicodeDecodeError: 'ascii' codec can't decode byte 0x8b in position 6: ordinal not in range(128) 

można jakoś przekształcić theiginal dataset na nowy, który będzie można odczytać z python3? Czy mogę w jakiś sposób odczytać go z python3 direrctly?

Próbowałem ładowania go przez cPickle, wysypywania go do json i czytając go z powrotem przez pickle, ale NumPy macierze oczywiście nie może być zapisany jako plik json.

Odpowiedz

5

Musisz podać pikselowi, jakiego kodeka użyć dla tych bajtów, lub powiedzieć, żeby załadował dane jako bytes. Od pickle.load() documentation:

The encoding and errors tell pickle how to decode 8-bit string instances pickled by Python 2; these default to ‘ASCII’ and ‘strict’, respectively. The encoding can be ‘bytes’ to read these 8-bit string instances as bytes objects.

Aby załadować sznurki jak bytes obiektów, które byłoby:

import pickle 
with open("data/data_batch_1", "rb") as f: 
    data = pickle.load(f, encoding='bytes') 
+1

tylko dla innych, którzy uważają to za pośrednictwem Google: jeśli zastosować tę poprawkę, a następnie pojawia się komunikat 'TypeError : musi to być znak Unicode, a nie bytes', twoja wersja numpy jest zbyt stara i ma [this] (https://github.com/numpy/numpy/issues/4879) błąd. –

+0

może lepiej używać latin1, a nie bajtów: –

+0

@ShimonDoodkin: to zależy całkowicie od danych. I tylko dlatego, że Latin-1 zawsze działa, nie oznacza, że ​​faktycznie masz dane Latin-1. –