Pickle onverenigbaar numpy arrays tussen Python 2 en 3

Ik ben op zoek naar de MNIST dataset laden gekoppeld hier in Python 3.2 gebruik van dit programma:

import pickle
import gzip
import numpy
with gzip.open('mnist.pkl.gz', 'rb') as f:
    l = list(pickle.load(f))
    print(l)

Helaas, het geeft me de fout:

Traceback (most recent call last):
   File "mnist.py", line 7, in <module>
     train_set, valid_set, test_set = pickle.load(f)
UnicodeDecodeError: 'ascii' codec can't decode byte 0x90 in position 614: ordinal not in range(128)

Vervolgens heb ik geprobeerd om het ingelegde bestand te decoderen in Python 2.7, en hercoderen. Dus, ik liep dit programma in Python 2.7:

import pickle
import gzip
import numpy
with gzip.open('mnist.pkl.gz', 'rb') as f:
    train_set, valid_set, test_set = pickle.load(f)
    # Printing out the three objects reveals that they are
    # all pairs containing numpy arrays.
    with gzip.open('mnistx.pkl.gz', 'wb') as g:
        pickle.dump(
            (train_set, valid_set, test_set),
            g,
            protocol=2)  # I also tried protocol 0.

Het liep zonder fouten, dus ik reran dit programma in Python 3.2:

import pickle
import gzip
import numpy
# note the filename change
with gzip.open('mnistx.pkl.gz', 'rb') as f:
    l = list(pickle.load(f))
    print(l)

Maar het gaf me de zelfde fout als voorheen. Hoe kan ik deze aan de slag?


Dit is een betere aanpak voor het laden van de MNIST dataset.


Antwoord 1, Autoriteit 100%

Dit lijkt een soort van incompatibiliteit. Het probeert om een ​​”binstring” object, waarvan wordt aangenomen dat ASCII te laden, terwijl in dit geval is het binaire data. Als dit is een fout in de Python 3 unpickler, of een “misbruik” van de pickler door numpy, weet ik niet.

Hier is iets van een tijdelijke oplossing, maar ik weet niet hoe belangrijk de gegevens is op dit punt:

import pickle
import gzip
import numpy
with open('mnist.pkl', 'rb') as f:
    u = pickle._Unpickler(f)
    u.encoding = 'latin1'
    p = u.load()
    print(p)

unpickling in Python 2 en vervolgens repickling is het alleen gaat om het zelfde probleem opnieuw te creëren, dus je moet het op te slaan in een ander formaat.


Antwoord 2, Autoriteit 98%

Als u krijgt deze fout in python3, dan, het zou een compatibiliteitsprobleem tussen python 2 en Python 3 zijn, voor mij de oplossing was om loadmet latin1coderende:

pickle.load(file, encoding='latin1')

Antwoord 3, Autoriteit 10%

Het lijkt een compatibiliteitsprobleem tussen de Python 2 en Python 3. Ik probeerde het laden van de MNIST dataset met

   train_set, valid_set, test_set = pickle.load(file, encoding='iso-8859-1')

en het werkte voor Python 3.5.2


Antwoord 4, Autoriteit 5%

Het lijkt erop dat zijn er een aantal compatablility oplossen in augurk tussen 2.x en 3.x te wijten aan de verhuizing naar unicode. Het bestand lijkt te worden gebeitst met python 2.x en decoderen in 3.x kan lastig.

zijn

Ik stel unpickelen met python 2.x en opslaan in een formaat dat speelt mooier over de twee versies die u gebruikt.


Antwoord 5, Autoriteit 5%

Ik struikelde over dit fragment. Hoop dat dit helpt om de compatibiliteit kwestie te verduidelijken.

import sys
with gzip.open('mnist.pkl.gz', 'rb') as f:
    if sys.version_info.major > 2:
        train_set, valid_set, test_set = pickle.load(f, encoding='latin1')
    else:
        train_set, valid_set, test_set = pickle.load(f)

Antwoord 6, autoriteit 5%

Probeer:

l = list(pickle.load(f, encoding='bytes')) #if you are loading image data or 
l = list(pickle.load(f, encoding='latin1')) #if you are loading text data

Uit de documentatie van de pickle.loadmethode:

Optionele trefwoordargumenten zijn fix_imports, codering en fouten, die worden gebruikt om de compatibiliteitsondersteuning te regelen voor augurkstream die wordt gegenereerd door Python 2.

Als fix_imports True is, zal augurk proberen de oude Python 2-namen toe te wijzen aan de nieuwe namen die in Python 3 worden gebruikt.

De codering en fouten vertellen augurk hoe 8-bit string-instanties moeten worden gedecodeerd die zijn gepekeld door Python 2; deze staan ​​standaard op respectievelijk ‘ASCII’ en ‘strikt’. De codering kan ‘bytes’ zijn om deze 8-bit string-instanties als bytes-objecten te lezen.


Antwoord 7

Er is hickle dat sneller is dan augurk en gemakkelijker.
Ik probeerde het op te slaan en te lezen in augurk, maar tijdens het lezen waren er veel problemen en verspilde ik een uur en vond ik nog steeds geen oplossing, hoewel ik aan mijn eigen gegevens werkte om een ​​chatbot te maken.

vec_xen vec_yzijn numpy arrays:

data=[vec_x,vec_y]
hkl.dump( data, 'new_data_file.hkl' )

Dan lees je het gewoon en voer je de bewerkingen uit:

data2 = hkl.load( 'new_data_file.hkl' )

Other episodes