根据NumPy文档here,默认情况下,矩阵会与allow_pickle=True
一起保存,而且,它们会说明此默认行为可能会出现问题:
allow_pickle:bool,可选
允许使用Python pickles保存对象数组。禁止泡菜的原因包括安全性(加载腌制数据可以执行任意代码)和可移植性(腌制对象可能无法在不同的Python安装上加载,例如,如果存储的对象需要不可用的库,并且并非所有的pickle数据都兼容Python 2和Python 3)。
默认值:True
阅读之后,我当然更喜欢使用allow_pickle=False
- 但是当它以这种方式使用时,它们并没有说明有什么不同。默认情况下,默认情况下,他们必须使用allow_pickel=True
。
您能告诉我您是否使用allow_pickle=False
以及它的行为方式有何不同?
答案 0 :(得分:5)
对象数组只是一个普通的numpy数组,dtype
是object
;如果数组的内容不是正常的数字类型(如int
或float
等),则会发生这种情况。我们可以试着用对象保存一个numpy数组,只是为了测试它是如何工作的。一种简单的对象是dict
:
>>> import numpy as np
>>> a = np.array([{x: 1} for x in range(4)])
>>> a
array([{0: 1}, {1: 1}, {2: 1}, {3: 1}], dtype=object)
>>> np.save('test.pkl', a)
加载此版本可以正常工作:
>>> np.load('test.pkl.npy')
array([{0: 1}, {1: 1}, {2: 1}, {3: 1}], dtype=object)
但是,如果不使用pickle,则无法保存数组:
>>> np.save('test.pkl', a, allow_pickle=False)
...
ValueError: Object arrays cannot be saved when allow_pickle=False
泡菜的经验法则是,如果你正在加载你制作的泡菜,那么你是安全的,但你应该小心加载从其他地方获得的泡菜。首先,如果您没有安装用于制作pickle的相同库(或库版本),则可能无法加载pickle(这就是 portability 的意思以上)。 安全性是另一个潜在的问题;例如,您可以在this article中阅读有关如何滥用泡菜的信息。