我最近遇到了numpy.savez和numpy.savez_compressed。两者似乎都能很好地处理不同类型的数组,包括对象数组。但是,numpy.load不能很好地处理对象类型数组。举例来说:
import numpy as np
numbers = np.full((10, 1), np.pi)
strings = np.full((10, 1), "letters", dtype=object)
np.savez("test.npz", numbers=numbers, strings=strings)
data = np.load("test.npz")
调用data["strings"]
会抛出以下ValueError:
ValueError: Object arrays cannot be loaded when allow_pickle=False
但是,在numpy.load
上启用pickle可以解决此问题。在numpy.savez
和numpy.savez_compressed
文档中没有讨论Pickling.这让我想知道为什么需要pickle来加载数据。numpy.savez
和numpy.savez_compressed
是否在后台自动使用pickle?
3条答案
按热度按时间vx6bjr1n1#
由于您有
dtype=object
,因此将使用pickle(序列化Python对象)。默认情况下,在保存时允许使用pickle序列化,但在加载时必须显式请求使用pickle序列化。这是因为加载pickle数据可能会执行任意代码,对于不受信任的输入,这将是一个安全问题。
qgzx9mmu2#
np.savez和np.savez_compressed在后台自动使用pickle吗?
对于对象类型数据,是的。
对于其他类型的数据,如浮点数、整型数、长整型数或字节,则不使用pickle。
对于np.save(),没有
allow_pickle
的等价物,因为加载pickle对象可能是一个安全问题,但保存pickle对象不是。xyhw6mcr3#
一般来说,是的,使用pickle模块。
在下面的源代码链接中查找“Loading files that contain object arrays uses the
pickle
module”。https://github.com/numpy/numpy/blob/v1.26.0/numpy/lib/npyio.py#L555-L639