问题:Python 2和3之间的numpy数组的Pickle不兼容
我正在尝试使用此程序加载在Python 3.2中链接到此处的MNIST数据集:
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)
但是,它给了我与以前相同的错误。我该如何工作?
回答 0
这似乎有点不兼容。它正在尝试加载一个假定为ASCII的“ binstring”对象,而在这种情况下,它是二进制数据。如果这是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中取消选择它,然后重新选择它只会再次导致相同的问题,因此您需要将其另存为另一种格式。
回答 1
如果您在python3中遇到此错误,则可能是python 2和python 3之间的不兼容问题,对我来说,解决方案是load
使用latin1
编码:
pickle.load(file, encoding='latin1')
回答 2
它似乎是Python 2和Python 3之间的不兼容问题。我尝试使用以下命令加载MNIST数据集:
train_set, valid_set, test_set = pickle.load(file, encoding='iso-8859-1')
它适用于Python 3.5.2
回答 3
由于迁移到unicode ,似乎在2.x和3.x之间的泡菜中存在一些兼容性问题。您的文件似乎已被python 2.x腌制,并且在3.x中对其进行解码可能很麻烦。
我建议用python 2.x将其解开,并保存为一种在您使用的两个版本中都能更好地播放的格式。
回答 4
我只是偶然发现了这个片段。希望这有助于澄清兼容性问题。
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)
回答 5
尝试:
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生成的pickle流的兼容性支持。
如果fix_imports为True,则pickle将尝试将旧的Python 2名称映射到Python 3中使用的新名称。
编码和错误告诉pickle如何解码Python 2腌制的8位字符串实例;它们分别默认为“ ASCII”和“ strict”。编码可以是“字节”,以将这些8位字符串实例读取为字节对象。
回答 6
有一个比泡菜快和容易的hi。我试图保存并在泡菜转储中阅读它,但是在阅读时有很多问题,浪费了一个小时,尽管我正在处理自己的数据以创建聊天机器人,但仍然找不到解决方案。
vec_x
并且vec_y
是numpy数组:
data=[vec_x,vec_y]
hkl.dump( data, 'new_data_file.hkl' )
然后,您只需阅读并执行以下操作:
data2 = hkl.load( 'new_data_file.hkl' )