Рассол несовместимость массивов между 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)
Однако, это дало мне ту же ошибку, что и раньше. Как мне заставить это работать?
7 ответов
Это похоже на какую-то несовместимость. Он пытается загрузить объект "binstring", который считается ASCII, в то время как в этом случае это двоичные данные. Если это ошибка в сборщике Python 3 или "неправильное использование" сборщиком по 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
Я просто наткнулся на этот фрагмент. Надеюсь, это поможет прояснить проблему совместимости.
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 между 2.x и 3.x из-за перехода на unicode. Похоже, что ваш файл засолен с помощью Python 2.x, и декодирование его в 3.x может быть проблематичным.
Я бы посоветовал снять его с python 2.x и сохранить в формате, который более удобен для всех двух версий, которые вы используете.
Пытаться:
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
Из документации pickle.load
метод:
Необязательными ключевыми аргументами являются fix_imports, кодировка и ошибки, которые используются для управления поддержкой совместимости для потока рассола, генерируемого Python 2.
Если fix_imports - True, Pickle попытается отобразить старые имена Python 2 на новые имена, используемые в Python 3.
Кодирование и ошибки сообщают pickle, как декодировать экземпляры 8-битных строк, выбранные Python 2; по умолчанию это ASCII и строгий, соответственно. Кодировка может быть "байтами" для чтения этих 8-битных строковых экземпляров как байтовых объектов.
Есть хикл, который быстрее, чем маринад, и легче. Я пытался сохранить и прочитать его в дампе, но во время чтения было много проблем, потраченных впустую час, и я так и не нашел решения, хотя работал над своими данными, чтобы создать чат-бота.
vec_x
а также vec_y
являются массивами NumPy:
data=[vec_x,vec_y]
hkl.dump( data, 'new_data_file.hkl' )
Затем вы просто читаете его и выполняете операции:
data2 = hkl.load( 'new_data_file.hkl' )