【问题标题】:Load Python 2 .npy file in Python 3在 Python 3 中加载 Python 2 .npy 文件
【发布时间】:2014-07-29 02:24:23
【问题描述】:

我正在尝试加载/usr/share/matplotlib/sample_data/goog.npy

datafile = matplotlib.cbook.get_sample_data('goog.npy', asfileobj=False)
np.load(datafile)

在 Python 2.7 中没问题,但在 Python 3.4 中引发异常:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xd4 in position 1: ordinal not in range(128)

我认为这与bytes/str/unicode Python 2 和 3 之间的不一致有关,但不知道如何解决。

问题:

  • 如何在 Python 3 中从 Python 2 加载 .npy 文件(NumPy 数据)?

【问题讨论】:

    标签: python python-3.x numpy python-unicode


    【解决方案1】:

    问题在于该文件包含序列化(腌制)的 Python 日期时间对象,而不仅仅是数字数据。这些对象的 Python 序列化格式在 Py2 到 Py3 之间不兼容:

    python2
    >>> import pickle
    >>> pickle.dumps(datetime.datetime.now())
    "cdatetime\ndatetime\np0\n(S'\\x07\\xde\\x06\\t\\x0c\\r\\x19\\x0f\\x1fP'\np1\ntp2\nRp3\n."
    

    python3
    >>> import pickle
    >>> pickle.loads(b"cdatetime\ndatetime\np0\n(S'\\x07\\xde\\x06\\t\\x0c\\r\\x19\\x0f\x1fP'\np1\ntp2\nRp3\n.")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xde in position 1: ordinal not in range(128)
    

    一种解决方法是更改​​ Numpy 代码内部

    numpy/lib/format.py:
    ...
    446         array = pickle.load(fp)
    

    array = pickle.load(fp, encoding="bytes")。更好的解决方案是允许numpy.load 传递编码参数。

    【讨论】:

    • 我根据你的更改但出现错误:TypeError: an integer is required (got type str),指向numpy/lib/format.py 的第 446 行。我的numpy版本是1.8.1,python版本是3.4.0。
    • 正确的选择似乎是encoding="bytes"而不是encoding="latin1"
    • 还是不行。 TypeError: must be a unicode character, not bytes
    • 在使用 Anaconda Python 3.4 的 Windows 系统上,它需要 encoding="bytes" 才能读取文件。访问数组需要 b'' 而不仅仅是 'name'。在 Linux 上,使用 3.4,我需要使用 encoding='latin1' 和 '' 来访问每个数组。
    • 差不多一年过去了,这似乎仍然是个问题,至少在 OS X 上是这样——其他人也是这样吗?为了加载一些(但不是全部)我的 .npy 文件(即我在大部分迁移到 python3 之前保存的那些),我真的不想更改原始的 numpy 代码。这似乎真的应该作为一个错误向 numpy 开发者社区提出。
    【解决方案2】:

    在带有 numpy 1.10.4 的 python 3.5 中,使用以下命令对我有用;

    D = np.load(file, encoding = 'latin1')
    

    当我不指定编码时,它会失败并显示相同的错误消息。

    【讨论】:

    • 我必须添加allow_pickle=True
    【解决方案3】:

    对我有帮助的一种解决方法是将 python2.* 中加载的 numpy 数组转储到 csv 文件,然后在 python3.* 中读回它

    # Dump in python2
    import numpy as np
    
    datafile = matplotlib.cbook.get_sample_data('goog.npy', asfileobj=False)
    arr = np.load(datafile)
    np.savetxt("np_arr.csv", arr, delimiter=",")
    

    现在在 python3 中读回文件

    # Load in python3
    import numpy as np
    arr = np.loadtxt(open("np_arr.csv"), delimiter=",")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-04
      • 2020-11-17
      • 2019-01-18
      • 2018-10-21
      • 2016-10-16
      • 1970-01-01
      • 2018-04-11
      相关资源
      最近更新 更多