【问题标题】:NumPy: consequences of using 'np.save()' with 'allow_pickle=False'NumPy:将 'np.save()' 与 'allow_pickle=False' 一起使用的后果
【发布时间】:2017-06-01 11:17:24
【问题描述】:

根据 NumPy 文档 here,默认情况下,矩阵会使用 allow_pickle=True 保存,此外,它们会告诉您此默认行为可能存在哪些问题:

allow_pickle : 布尔型,可选
允许使用 Python pickles 保存对象数组。不允许 pickle 的原因包括安全性(加载 pickle 数据可以执行任意代码)和可移植性(pickled 对象可能无法在不同的 Python 安装上加载,例如,如果存储的对象需要不可用的库,并且并非所有 pickle 数据在Python 2 和 Python 3)。
默认值:真

读完之后,我当然更喜欢使用allow_pickle=False——但他们并没有说明这样使用时有什么不同。尽管有缺点,但他们默认使用allow_pickel=True 肯定是有原因的。

能否请您说明您是否使用allow_pickle=False 以及它的行为有何不同?

【问题讨论】:

  • 我猜(所以不写答案)NumPy 使用 pickle 模块来保存非标准对象,因此通过禁用它,您可以限制您的代码在标准数据类型上工作。
  • 听起来很有趣也很有道理。您的意思是,如果我有一些类将其实例保存在 NumPy 数组中,那么如果我禁用 pickle,它将无法保存矩阵内容.. 对吗?

标签: python numpy


【解决方案1】:

对象数组只是一个普通的numpy数组,其中dtypeobject;如果数组的内容不是正常的数字类型(如intfloat 等),就会发生这种情况。我们可以尝试用对象保存一个 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

泡菜的经验法则是,如果您加载的是自己制作的泡菜,那么您是安全的,但您应该小心加载从其他地方获得的泡菜。一方面,如果您没有安装用于制作泡菜的相同库(或库版本),您可能无法加载泡菜(这就是可移植性的意思更多)。 安全是另一个潜在的问题;例如,您可以在this article 中阅读有关泡菜如何被滥用的一些信息。

【讨论】:

  • 也许澄清一下(我在阅读时并不清楚):保存机器整数、浮点数等的 numpy 数组不需要酸洗,并且在这种情况下,无论 allow_pickle 如何,numpy 都不会使用酸洗.在不禁用 pickle 的情况下调用 load 仍然会受到故意制造的文件的攻击。
猜你喜欢
  • 1970-01-01
  • 2011-08-18
  • 2014-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-07
  • 2021-01-04
  • 1970-01-01
相关资源
最近更新 更多