检查多维numpy数组的所有边是否都是零数组

Luc*_*uca 13 python numpy

一个 n 维数组有 2n 个边(一个一维数组有 2 个端点;一个二维数组有 4 个边或边;一个 3 维数组有 6 个二维面;一个 4 维数组有 8 个边;等等。)。这类似于抽象的 n 维立方体所发生的情况。

我想检查一个 n 维数组的所有边是否只由零组成。以下是边由零组成的数组的三个示例:

# 1D
np.array([0,1,2,3,0])
# 2D
np.array([[0, 0, 0, 0],
          [0, 1, 0, 0],
          [0, 2, 3, 0],
          [0, 0, 1, 0],
          [0, 0, 0, 0]])
# 3D
np.array([[[0, 0, 0, 0],
           [0, 0, 0, 0],
           [0, 0, 0, 0]],
          [[0, 0, 0, 0],
           [0, 1, 2, 0],
           [0, 0, 0, 0]],
          [[0, 0, 0, 0],
           [0, 0, 0, 0],
           [0, 0, 0, 0]]])
Run Code Online (Sandbox Code Playgroud)

如何检查多维 numpy 数组的所有边是否都是零数组?例如,使用一个简单的二维数组,我可以这样做:

x = np.random.rand(5, 5)
assert np.sum(x[0:,  0]) == 0
assert np.sum(x[0,  0:]) == 0
assert np.sum(x[0:, -1]) == 0
assert np.sum(x[-1, 0:]) == 0
Run Code Online (Sandbox Code Playgroud)

虽然这种方法适用于 2D 情况,但它不能推广到更高的维度。我想知道是否有一些聪明的 numpy 技巧可以在这里使用以使其高效且更易于维护。

Ric*_*cco 7

您可以这样做:

assert(all(np.all(np.take(x, index, axis=axis) == 0)
           for axis in range(x.ndim)
           for index in (0, -1)))
Run Code Online (Sandbox Code Playgroud)

np.take 与“花式”索引做同样的事情。

  • 此外,使用列表理解可以防止“all”短路。您可以删除括号以使用生成器表达式,从而允许在单个“numpy.all”调用返回“False”时立即返回“all”。 (5认同)

use*_*ica 5

这是一个实际检查您感兴趣的数组部分的答案,并且不会浪费时间构建整个数组大小的掩码。有一个 Python 级别的循环,但它很短,迭代与维数而不是数组的大小成正比。

def all_borders_zero(array):
    if not array.ndim:
        raise ValueError("0-dimensional arrays not supported")
    for dim in range(array.ndim):
        view = numpy.moveaxis(array, dim, 0)
        if not (view[0] == 0).all():
            return False
        if not (view[-1] == 0).all():
            return False
    return True
Run Code Online (Sandbox Code Playgroud)