2012-07-03 2 views
83

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

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) 

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


This is a better approach for loading the MNIST dataset.

+0

есть разрывы совместимости между 2.7 и 3.x. особенно string vs unicode. И для выбора объекта numpy требуется, чтобы обе системы загружали модуль numpy, но эти модули различны. Извините, у меня нет ответа, но это может быть неудобно и, вероятно, не рекомендуется. Если это большие вещи (gzip), возможно hdf5 с pytables ?? –

+0

@PhilCooper: Спасибо, ваш комментарий (опубликуйте это как ответ?) Подвел меня к правильному ответу. Я мог бы использовать hdf5, но мне было сложно учиться, поэтому я пошел с numpy.сохранить/загрузить, и это сработало. –

+0

h5py очень прост в использовании, почти наверняка намного проще, чем решить проблемы с туманной совместимостью с маринованием массивов numpy. – DaveP

ответ

50

Это похоже на несовместимость. Он пытается загрузить объект «binstring», который предполагается ASCII, тогда как в этом случае это двоичные данные. Если это ошибка в неуправляемом Python 3 или «неправильном использовании» pickler 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) 

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

+1

Спасибо за внимание! –

+119

Вы можете использовать 'pickle.load (file_obj, encoding = 'latin1')' (по крайней мере, в Python 3.3). Это нужно для работы. –

+4

Для тех, кто использует нагрузку numpy и сталкивается с аналогичной проблемой: можно также пропустить кодировку: 'np.load ('./bvlc_alexnet.npy', encoding = 'latin1')' –

5

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

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

+1

Вот что я пытался сделать. Какой формат вы рекомендуете? –

+5

Я думаю, что проблема, возможно, заключалась в кодировании numpy dtype, который может быть строкой. В любом случае, я закончил использование numpy.save/load, чтобы устранить разрыв между python 2 и 3, и это сработало. –

40

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

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

Точно то, что мне нужно. Благодаря! – misterkugelblitz

7

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

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

и он работал на Python 3.5.2

0

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

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) 
+0

Рассмотрите возможность добавления более подробной информации. Как это решить проблему? –