【问题标题】:Numpy: are bound checks necessary when slicing arraysNumpy:切片数组时是否需要进行绑定检查
【发布时间】:2021-07-07 17:40:21
【问题描述】:

如果你这样做,例如以下:

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

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

【问题讨论】:

  • numpy 从 Python 列表中继承了这种行为(至少在概念上如此),而且它从一开始就是标准行为。您无法在界限之外建立索引。主要(唯一?)缺点是您最终可能会得到一个小于预期的数组,甚至可能在 siced 维度中大小为 0。但你知道这一点。
  • 谢谢,这很有帮助!

标签: python python-3.x numpy indexing


【解决方案1】:

切片解析不是在 numpy 中完成的。 slice 对象有一个方便的方法,称为indices 方法,它只记录在PySlice_GetIndices 下的C API 中。事实上,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]])

【讨论】:

  • 感谢您的深入回答。因为我只会使用 a[x:y] 进行索引,所以一切都只能通过切片对象来处理,对吧?所以我假设我不需要边界检查(请参阅问题下方的评论)
  • @Pinko。这是非常正确的。检查将通过slice 在后台为您实施
猜你喜欢
  • 2019-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-24
  • 2012-11-19
  • 1970-01-01
相关资源
最近更新 更多