Check If All Sides Of A Multidimensional Numpy Array Are Arrays Of Zeros
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"