首页 > 解决方案 > Numpy:切片数组时是否需要进行绑定检查

问题描述

如果您执行以下操作:

a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15]])
print(a[2:10])

Python 不会抱怨并打印数组,因为a[2:]这在我的用例中会很棒。我想遍历一个大数组并将其切成大小相等的块,直到数组“用完”。因此,最后一个数组可以比其他数组小,这对我来说并不重要。

但是:我担心安全漏洞,性能漏洞,这种行为在不久的将来被弃用的可能性等等。它是否安全并且打算使用这样的切片,或者应该避免它,我必须去加倍努力以确保最后一块被切成a[2:]a[2:len(a)]

有类似这样的相关答案,但我没有找到任何解决我问题的方法

标签: pythonpython-3.xnumpyindexing

解决方案


切片解析不是在 numpy 中完成的。slice对象有一个名为indicesmethod 的便捷方法,该方法仅记录在 C API 的PySlice_GetIndices. 事实上,python 文档指出它们除了存储索引之外没有其他功能。

运行a[2:10]时,切片对象为slice(2, 10),轴的长度为a.shape[0] == 5

>>> slice(2, 10).indices(5)
(2, 5, 1)

这是内置的 python 行为,比 numpy 级别低。链接的问题有一个获取相应索引错误的示例:

>>> a[np.arange(2, 10)]

在这种情况下,传递的对象不是切片,因此它确实由 numpy 处理,并引发错误:

IndexError: index 5 is out of bounds for axis 0 with size 5

如果您尝试单独访问无效索引,则会遇到相同的错误:

>>> a[5]
...
IndexError: index 5 is out of bounds for axis 0 with size 5

顺便说一句,python 列表和元组也会检查标量索引的边界:

>>> a.tolist()[5]
...
IndexError: list index out of range

您可以实现自己的边界检查,例如使用以下命令创建精美的索引slice.indices

>>> a[np.arange(*slice(2, 10).indices(a.shape[0]))]
array([[ 7,  8,  9],
       [10, 11, 12],
       [13, 14, 15]])

推荐阅读