带有 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 文件中的数组切片?