繁体   English   中英

Python 2 和 3 之间 numpy 数组的 Pickle 不兼容

[英]Pickle incompatibility of numpy arrays between Python 2 and 3

我正在尝试使用此程序在 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)

但是,它给了我与以前相同的错误。 我如何让这个工作?


这是加载 MNIST 数据集的更好方法。

这似乎是某种不兼容。 它试图加载一个“binstring”对象,假设它是 ASCII,而在这种情况下它是二进制数据。 如果这是 Python 3 unpickler 中的错误,或者是 numpy 对pickler 的“误用”,我不知道。

这是一种解决方法,但我不知道此时数据的意义有多大:

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 latin1编码:

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

由于转向 unicode,2.x 和 3.x 之间的 pickle 似乎存在一些兼容性问题 您的文件似乎是用 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)

尝试:

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、encoding 和 errors,用于控制对 Python 2 生成的 pickle 流的兼容性支持。

如果 fix_imports 为 True,pickle 将尝试将旧的 Python 2 名称映射到 Python 3 中使用的新名称。

编码和错误告诉 pickle 如何解码 Python 2 腌制的 8 位字符串实例; 这些分别默认为 'ASCII' 和 'strict'。 编码可以是“字节”,以将这些 8 位字符串实例作为字节对象读取。

有比泡菜更快更容易的 hickle。 我试图在 pickle dump 中保存和阅读它,但在阅读时出现了很多问题,浪费了一个小时,尽管我正在使用自己的数据来创建聊天机器人,但仍然没有找到解决方案。

vec_xvec_y是 numpy 数组:

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

然后你只需阅读它并执行操作:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM