所有concatenate(stack 只是另一种调用方式)创建一个带有自己的数据缓冲区的数组。它绝不是原件的view。
您的 rv0 是一个数组 (np.ndarray),类似于 recs,具有自己的形状、dtype 和步幅。它只是与recs 共享数据缓冲区。它可以被描述为recs 的“视图”,但除此之外,它就像任何其他数组一样使用。它没有特别标记为view 类或对象。
In [409]: recs = np.arange(2*2).reshape(2,2)
...: recs2 = np.arange(4,2*2*2).reshape(2,2)
由于recs 是由arange 生成的数组的reshape,因此它也是“视图”。这可以通过以下方式变得更加明显:
temp = np.arange(2*2)
recs = temp.reshape(2,2)
np.may_share_memory(temp, recs)
我们可以通过ravel() 获取数据缓冲区的快照(可以说是生成一维视图):
In [411]: recs.ravel()
Out[411]: array([0, 1, 2, 3])
In [412]: recs2.ravel()
Out[412]: array([4, 5, 6, 7])
现在看stack:
In [414]: mview = np.stack([recs,recs2], axis=0)
In [415]: mview
Out[415]:
array([[[0, 1],
[2, 3]],
[[4, 5],
[6, 7]]])
In [416]: mview.ravel()
Out[416]: array([0, 1, 2, 3, 4, 5, 6, 7])
mview 的 ravel 不是 Out[411] 和 Out[412] 的子集。 mview 必须有自己的连续数据缓冲区。没有机制可以使数组与 2 个或更多其他数组共享内存(除非它们也共享内存)。
即使是由同一数组的切片组成的 stack 也有自己的数据缓冲区:
In [420]: x = np.stack((recs[0],recs[1]))
In [421]: x
Out[421]:
array([[0, 1],
[2, 3]])
In [422]: np.may_share_memory(recs, x)
Out[422]: False
我喜欢使用__array_interface__ 来检查数据缓冲区的位置(其他定义属性):
In [423]: recs.__array_interface__
Out[423]:
{'data': (37584304, False),
'strides': None,
'descr': [('', '<i8')],
'typestr': '<i8',
'shape': (2, 2),
'version': 3}
In [424]: x.__array_interface__
Out[424]:
{'data': (37614336, False),
'strides': None,
'descr': [('', '<i8')],
'typestr': '<i8',
'shape': (2, 2),
'version': 3}