다차원 numpy 배열에 모든면에 0이 있는지 확인하는 가장 빠른 방법은 무엇입니까?
따라서 간단한 2D 예를 들면 다음과 같습니다.
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
이것은 2D 사례에는 적합하지만 더 큰 치수를 작성하는 것은 약간 지루한 일이며 효율적이고 유지 관리하기 위해 여기에 사용할 수있는 영리한 수 많은 트릭이 있는지 궁금합니다.
답변
이를 수행하는 방법은 다음과 같습니다.
assert(all(np.all(np.take(x, index, axis=axis) == 0)
for axis in range(x.ndim)
for index in (0, -1)))
np.take
“팬시”인덱싱과 같은 일을합니다.
답변
다음은 실제로 관심있는 배열 부분을 검사하고 전체 배열의 크기로 마스크를 구성하는 데 시간을 낭비하지 않는 대답입니다. 파이썬 수준의 루프가 있지만 배열 크기 대신 차원 수에 비례하여 반복이 짧습니다.
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
답변
나는 배열을 재구성 한 다음 반복했습니다. 불행히도, 내 대답은 적어도 3 차원이 있다고 가정하고 일반 행렬에 대해 오류가 발생한다고 가정하면 1 차원 및 2 차원 모양 배열에 대한 특수 절을 추가해야합니다. 또한 속도가 느려서 더 나은 솔루션이있을 수 있습니다.
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 in range(chunk):
z = x[block*idx[-2]:(block+1)*idx[-2], :]
if not np.all(z[:, 0] == 0):
return False
if not np.all(z[:, -1] == 0):
return False
if not np.all(z[0, :] == 0):
return False
if not np.all(z[-1, :] == 0):
return False
return True
어떤 생산
>>> False
>>> True
기본적으로 모든 치수를 서로 쌓은 다음 가장자리를 확인하기 위해 치수를 살펴 봅니다.
답변
아마도 줄임표 연산자는 당신이 찾고있는 것일 것입니다.
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)
답변
slice
작업을 완료하기 위해 부울 마스킹을 사용할 수 있습니다 .
def get_borders(arr):
s=tuple(slice(1,i-1) for i in a.shape)
mask = np.ones(arr.shape, dtype=bool)
mask[s] = False
return(arr[mask])
이 함수는 먼저 배열의 “코어”를 튜플 형태로 s
만든 다음 경계점 True
에만 표시되는 마스크를 만듭니다 . 부울 인덱싱은 경계점을 제공합니다.
작업 예 :
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])
그런 다음 np.all(borders==0)
원하는 정보를 제공합니다.
참고 : 이것은 1 차원 배열에서는 깨지기는하지만 가장자리를 고려합니다. 문제의 두 지점을 확인하는 것이 좋습니다.