Pickle несовместимость массивов numpy между Python 2 и 3


Я пытаюсь загрузить связанный набор данных MNIST здесь в Python 3.2 с помощью этой программы:

import pickle
import gzip
import numpy


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

к сожалению, это дает мне ошибку:

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)

затем я попытался декодировать маринованный файл в Python 2.7 и перекодировать его. Итак, я запустил эту программу в 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.

он работал без ошибок, поэтому я повторно запускаю эту программу в 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)

однако, это дало мне ту же ошибку, что и раньше. Как мне это сделать работа?


это лучший подход для загрузки набора данных MNIST.

6 106

6 ответов:

это похоже на какую-то несовместимость. Он пытается загрузить объект "binstring", который считается ASCII, в то время как в этом случае это двоичные данные. Если это ошибка в Python 3 unpickler или" неправильное использование " пиклера numpy, я не знаю.

вот что-то вроде обходного пути, но я не знаю, насколько значимы данные на данный момент:

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)

распаковывая его в Python 2, а затем переупаковывая его, вы снова создадите ту же проблему, поэтому нужно сохранить его в другом формате.

Если вы получаете эту ошибку в python3, то, это может быть проблема несовместимости между python 2 и python 3, для меня решение было load С lattin1 кодировка:

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

Это, кажется, проблема несовместимости между Python 2 и Python 3. Я попытался загрузить набор данных MNIST с помощью

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

и это сработало для Python 3.5.2

похоже есть некоторые проблемы совместимости в рассоле между 2.x и 3.x из-за перехода на Юникод. Ваш файл, похоже, замаринован с python 2.x и декодирование его в 3.x может быть неприятным.

Я бы предложил распаковывать его с помощью python 2.x и сохранение в формат, который играет более красиво в двух версиях, которые вы используете.

Я просто наткнулся на этот фрагмент. Надеюсь, это поможет прояснить проблему совместимости.

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)

есть хикл, который быстрее, чем рассол и проще. Я попытался сохранить и прочитать его в pickle dump, но во время чтения было много проблем и потратил впустую час и до сих пор не нашел решения, хотя я работал над своими собственными данными, чтобы создать чат-бота.

vec_x и vec_y массивы numpy:

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

затем вы просто читаете его и выполняете операции:

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