带有 2D 切片的 numpy 视图

Posted

技术标签:

【中文标题】带有 2D 切片的 numpy 视图【英文标题】:view of numpy with 2D slicing 【发布时间】:2021-07-03 10:49:24 【问题描述】:

Numpy 使用视图对象来最小化内存复制。下面的代码使用索引列表对原始 ndarray 进行切片。结果是None,这意味着arr[ [0, 3] ]被分配了自己的内存。

arr = np.arange(5)
print(arr[ [0, 3] ].base)

在范围切片的情况下,arr[0:2] 返回指向原始 ndarray ([0 1 2 3 4]) 的视图

print(arr[ 0:2 ].base)

在 2D 切片的情况下,它的工作方式与我预期的打印输出 None 不同。

arr = np.array([
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
])

print(arr[  : , [0, 2] ].base )
[[0 3 6]
 [2 5 8]]

我想知道为什么 None 没有返回,为什么 base 的形状不是 (3, 2)。

【问题讨论】:

【参考方案1】:
In [205]: arr = np.array([
     ...:     [0, 1, 2],
     ...:     [3, 4, 5],
     ...:     [6, 7, 8],
     ...: ])
     ...: 
     ...: arr[  : , [0, 2] ]
Out[205]: 
array([[0, 2],
       [3, 5],
       [6, 8]])

数组索引符合我们的预期。只是base 不同。

In [206]: _.base
Out[206]: 
array([[0, 3, 6],
       [2, 5, 8]])

我认为base 提供了有关索引基础过程的线索。它使用[0,2] 高级索引制作了一个副本,并执行了某种转置以返回所需的数组。

我还没有完全关注base。如果对某个东西是否是视图有疑问,我喜欢比较__array_interface__ .

通常知道data 值明显不同(而不仅仅是偏移量)就足够了。

In [209]: arr.__array_interface__
Out[209]: 
'data': (38026368, False),
 'strides': None,
 'descr': [('', '<i8')],
 'typestr': '<i8',
 'shape': (3, 3),
 'version': 3
In [210]: arr[  : , [0, 2] ].__array_interface__
Out[210]: 
'data': (38386288, False),
 'strides': (8, 24),
 'descr': [('', '<i8')],
 'typestr': '<i8',
 'shape': (3, 2),
 'version': 3

进一步看strides

In [218]: arr.strides
Out[218]: (24, 8)
In [219]: arr[:,[0,2]].strides
Out[219]: (8, 24)
In [220]: arr[:,[0,2]].copy().strides
Out[220]: (16, 8)

arr strides 是(3*8, 8),因为进入下一行意味着跳过 3 列值。但是索引的步幅是相反的,这是我对 base 的转置所期望的。完整的副本是(2*8,8),反映了 2 列的形状。

所以这里base 揭示了索引过程的细节。我以前没有注意到这些,而且我已经使用numpy 有一段时间了。


base 反映构造过程的另一种情况是通过arange 制作您的arr

In [213]: np.arange(9).reshape(3,3).base
Out[213]: array([0, 1, 2, 3, 4, 5, 6, 7, 8])

base 来自 arange,但我们从未分配给变量。

【讨论】:

以上是关于带有 2D 切片的 numpy 视图的主要内容,如果未能解决你的问题,请参考以下文章

如何在 pyqtgraph 远程视图上绘制切片的 numpy 数据数组

有没有办法让一个 numpy 样式的视图查看存储在 hdf5 文件中的数组切片?

numpy切片和布尔型索引

基于 2D 数组的 3D numpy 切片的平均值

NumPy:在 3D 切片中使用来自 argmin 的 2D 索引数组

Numpy | 20 副本和视图