通过沿一个轴堆叠将两个numpy视图合并为一个视图

时间:2019-01-13 15:59:30

标签: python numpy view

从概念上讲,我是否没有掌握任何内容(仅类似question),或者为什么沿第一个axis=0堆叠多个视图不会产生新视图?问题:多个2d数组,其中的单行应合并为一个新的矩阵,这也是不增加内存使用量的一种观点。例如:

recs = np.arange(2*2).reshape(2,2)
recs2 = np.arange(4,2*2*2).reshape(2,2)
print(recs)
print(recs2)
rv0 = recs[0].view()
r2v0 = recs2[0].view()
#now combine
mview = np.stack([rv0,r2v0], axis=0)
print(mview)
np.may_share_memory(mview,recs2)

打印

[[0 1]
 [2 3]]
[[4 5]
 [6 7]]
[[0 1]
 [4 5]]
False #sure a copy

是因为二维数组是单独的内存区域,并且生成的数组不允许切片等吗?

1 个答案:

答案 0 :(得分:2)

所有concatenatestack只是调用它的另一种方式)使用自己的数据缓冲区创建一个数组。它绝不是原始文件的view

您的rv0np.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)

由于recsreshape产生的数组的arange,因此它也是“视图”。可以通过以下方法使这种情况更加明显:

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])

ravel的{​​{1}}不是mviewOut[411]的子集。 Out[412]必须具有自己的连续数据缓冲区。没有一种机制可以使阵列与2个或更多其他阵列共享内存(除非它们也共享内存)。


即使是由同一数组的切片组成的mview也有自己的数据缓冲区:

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__