我有以下两难境地。我正在尝试对表示图像的麻木数组进行筛选,然后再将其取消筛选。
执行此代码:
a1 = np.zeros((1080, 1920, 3), dtype=np.uint8)
print(sys.getsizeof(a1), a1.shape)
a2 = pickle.dumps(a1)
print(sys.getsizeof(a2), type(a2))
a3 = pickle.loads(a2)
print(sys.getsizeof(a3), a3.shape)
生成以下输出:
6220928 (1080, 1920, 3)
6220995 <class 'bytes'>
128 (1080, 1920, 3)
现在,a1
大约是6 MB,a2
是a1
的泡菜表示形式,虽然稍长一些,但仍然大致相同。然后我试着解开a2
然后我得到..。一些明显不对劲的事情。a3
看起来很好,我可以调用方法,我可以给它的单元格赋值等。
如果我用a1.dumps
和np.loads
替换Pickle调用,结果是一样的,因为这两个调用只是调用Pickle。
那么,这种奇怪的尺寸到底是怎么回事?
3条答案
按热度按时间k97glaaz1#
从
sys.getsizeof
文档:以字节为单位返回对象的大小。该对象可以是任何类型的对象。所有内置对象都将返回正确的结果,但这不一定适用于第三方扩展,因为它是特定于实现的。
重点是我的。基本上,不能保证
sys.getsizeof
会为NumPy对象提供一致或正确的值。czq61nw12#
制作阵列和转储。它不一定非得很大。
nbytes
匹配,形状也匹配由于
a3
的getsizeof
很小,我怀疑它是一个view
的东西。也就是说,getsizeof
没有‘看到’它的数据缓冲区。如果数组有自己的数据,则
base
将是None
。或者它可以是另一个阵列的view
。但显然loads
通过引用bytes
对象构造了这个数组:这看起来像没有某种信息头的
a2
。无论如何,在检查数组或列表时,
getsizeof
并不是那么有用。下面是一个更简单的案例,其中包含一个常见的测试数组:
x
实际上是arange
创建的数组的view
。编辑
我怀疑
a3
是使用类似以下内容创建的:另一个注意事项-
pickle
允许对象指定它将如何被序列化。对于ndarray
,这是使用np.save
代码完成的。格式是头缓冲区,后跟数组数据缓冲区的副本。bq3bfh9z3#
这是因为a3对象并不拥有ndarray内存,而是将其指向a3.base。因此,sys.getsizeof(A3)不会报告a3.base内存大小。
相反,a1对象确实拥有它的内存(因为a1.base为None,请通过说Help(A1)来检查ndarray的.base的解释)。因此,sys.getsizeof(A1)报告包括整个数组在内的内存大小。
查看更多关于内存使用的讨论here。
因此,有时sys.getsizeof()可能不会给您带来直观的结果,这取决于您想要实现什么。这主要取决于您对“对象存储”的定义。