我刚注意到:
import numpy as np import sys arr = np.broadcast_to(0, (10, 1000000000000)) print(arr.nbytes) # prints "80000000000000" print(sys.getsizeof(arr)) # prints "120"
这是一个bug还是预期行为?即,nbytes是否意味着保存“逻辑”字节的数量,而不是0步?
nbytes
p1tboqfb1#
虽然我没有看到它的文档,但nbytes看起来确实像是shape和itemsize的乘积,或者arr.size*arr.itemsize。在所有的例子中,我都看到nbytes使用了shape/size数组,而不是base,所以我不会过多地阅读文档中使用的“consumed”。您的示例:
itemsize
arr.size*arr.itemsize
base
In [117]: arr = np.broadcast_to(0,(1,2,3)) In [119]: arr.shape, arr.strides, arr.nbytes Out[119]: ((1, 2, 3), (0, 0, 0), 24) In [120]: arr.base Out[120]: array(0) In [121]: arr.base.nbytes Out[121]: 4
广播数组是一个小得多的数组的view; nbytes反映其自身的形状,而不是基底的形状。再举一个例子,其中view是基的子集:
view
In [122]: np.arange(100).nbytes Out[122]: 400 In [123]: np.arange(100)[::4].nbytes Out[123]: 100
broadcast_to的代码可以在np.lib.stride_tricks._broadcast_to中查看,它使用np.nditer生成新视图。sys.getsizeof可以合理地返回数组的内存使用情况及其on数据(即base是None)。它不提供任何有关view的有用信息。
broadcast_to
np.lib.stride_tricks._broadcast_to
np.nditer
sys.getsizeof
None
另一个用于创建“更大”数组的跨步技巧示例:
In [180]: arr = np.arange(16).reshape(4,4).copy() In [181]: arr.shape, arr.strides, arr.nbytes Out[181]: ((4, 4), (16, 4), 64) In [182]: res = np.lib.stride_tricks.sliding_window_view(arr,(2,2)) In [183]: res.shape, res.strides, res.nbytes Out[183]: ((3, 3, 2, 2), (16, 4, 16, 4), 144)
它是原始的(4,4)arr的view:
arr
In [184]: res.base Out[184]: <numpy.lib.stride_tricks.DummyArray at 0x1fa8e7cc730> In [185]: res.base.base Out[185]: array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11], [12, 13, 14, 15]]) In [186]: res.base.base is arr Out[186]: True
1条答案
按热度按时间p1tboqfb1#
虽然我没有看到它的文档,但
nbytes
看起来确实像是shape和itemsize
的乘积,或者arr.size*arr.itemsize
。在所有的例子中,我都看到
nbytes
使用了shape/size数组,而不是base
,所以我不会过多地阅读文档中使用的“consumed”。您的示例:
广播数组是一个小得多的数组的
view
;nbytes
反映其自身的形状,而不是基底的形状。再举一个例子,其中
view
是基的子集:broadcast_to
的代码可以在np.lib.stride_tricks._broadcast_to
中查看,它使用np.nditer
生成新视图。sys.getsizeof
可以合理地返回数组的内存使用情况及其on数据(即base
是None
)。它不提供任何有关view
的有用信息。滑动窗口
另一个用于创建“更大”数组的跨步技巧示例:
它是原始的(4,4)
arr
的view
: