Skip to content Skip to sidebar Skip to footer

Check If All Sides Of A Multidimensional Numpy Array Are Arrays Of Zeros

An n-dimensional array has 2n sides (a 1-dimensional array has 2 endpoints; a 2-dimensional array has 4 sides or edges; a 3-dimensional array has 6 2-dimensional faces; a 4-dimensi

Solution 1:

Here's how you can do it:

assert(all(np.all(np.take(x, index, axis=axis) == 0)
           for axis inrange(x.ndim)
           for index in (0, -1)))

np.take does the same thing as "fancy" indexing.

Solution 2:

Here's an answer that actually examines the parts of the array you're interested in, and doesn't waste time constructing a mask the size of the whole array. There's a Python-level loop, but it's short, with iterations proportional to the number of dimensions instead of the array's size.

def all_borders_zero(array):
    if not array.ndim:
        raise ValueError("0-dimensional arrays not supported")
    for dim inrange(array.ndim):
        view= numpy.moveaxis(array, dim, 0)
        if not (view[0] ==0).all():
            returnFalse
        if not (view[-1] ==0).all():
            returnFalsereturnTrue

Solution 3:

I reshaped the array and then iterated through it. Unfortunately, my answer assumes you have at least three dimensions and will error out for normal matrices, you would have to add a special clause for 1 & 2 dimensional shaped arrays. In addition, this will be slow so there are likely better solutions.

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

xx = np.array(
        [
            [
                [0 , 0, 0, 0],
                [0 , 2, 3, 0],
                [0 , 0, 0, 0]
            ],
            [
                [0 , 0, 0, 0],
                [0 , 7, 8, 0],
                [0 , 0, 0, 0]
            ]
        ])

def check_edges(x):

    idx = x.shape
    chunk = np.prod(idx[:-2])
    x = x.reshape((chunk*idx[-2], idx[-1]))
    for block inrange(chunk):
        z = x[block*idx[-2]:(block+1)*idx[-2], :]
        ifnot np.all(z[:, 0] == 0):
            return False
        ifnot np.all(z[:, -1] == 0):
            return False
        ifnot np.all(z[0, :] == 0):
            return False
        ifnot np.all(z[-1, :] == 0):
            return False

    return True

Which will produce

>>>False>>>True

Basically I stack all the dimensions on top of each other and then look through them to check their edges.

Solution 4:

maybe the ellipsis operator is what you are looking for, which will work for many dimensions:

import numpy as np

# data
x = np.random.rand(2, 5, 5)
x[..., 0:, 0] = 0
x[..., 0, 0:] = 0
x[..., 0:, -1] = 0
x[..., -1, 0:] = 0

test = np.all(
    [
        np.all(x[..., 0:, 0] == 0),
        np.all(x[..., 0, 0:] == 0),
        np.all(x[..., 0:, -1] == 0),
        np.all(x[..., -1, 0:] == 0),
    ]
)

print(test)

Solution 5:

You can make use of slice and boolean masking to get the job done:

defget_borders(arr):
    s=tuple(slice(1,i-1) for i in a.shape)
    mask = np.ones(arr.shape, dtype=bool)
    mask[s] = Falsereturn(arr[mask])

This function first shapes the "core" of the array into the tuple s, and then builds a mask that shows True only for the bordering points. Boolean indexing then delivers the border points.

Working example:

a = np.arange(16).reshape((4,4))

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

borders = get_borders(a)
print(borders)
array([ 0,  1,  2,  3,  4,  7,  8, 11, 12, 13, 14, 15])

Then, np.all(borders==0) will give you the desired information.


Note: this breaks for one-dimensional arrays, though I consider those an edge case. You're probably better off just checking the two points in question there

Post a Comment for "Check If All Sides Of A Multidimensional Numpy Array Are Arrays Of Zeros"