在Python 3中加载Python 2 .npy文件

时间:2014-06-08 10:21:53

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

我试图加载/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)

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

问题:

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

3 个答案:

答案 0 :(得分:6)

问题是该文件包含序列化(pickled)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传递编码参数。

答案 1 :(得分:3)

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

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

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

答案 2 :(得分:1)

帮助我的一个解决方法是将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=",")