[python] 두 개 이상의 인수에 대한 Numpy`logical_or`
Numpy의 logical_or
함수는 비교할 배열을 두 개 이상 사용하지 않습니다. 두 개 이상의 배열의 합집합을 어떻게 찾을 수 있습니까? (Numpy logical_and
와 두 개 이상의 배열의 교차점에 대해 동일한 질문을 할 수 있습니다 .)
답변
에 대해 묻는 경우 numpy.logical_or
문서에서 명시 적으로 말했듯이 유일한 매개 변수는 x1, x2
이며 선택적으로 out
다음 과 같습니다.
numpy.
logical_or
(x1, x2[, out]
) =<ufunc 'logical_or'>
물론 다음과 같이 여러 logical_or
호출을 함께 연결할 수 있습니다 .
>>> x = np.array([True, True, False, False])
>>> y = np.array([True, False, True, False])
>>> z = np.array([False, False, False, False])
>>> np.logical_or(np.logical_or(x, y), z)
array([ True, True, True, False], dtype=bool)
NumPy에서 이러한 종류의 체인을 일반화하는 방법은 다음과 reduce
같습니다.
>>> np.logical_or.reduce((x, y, z))
array([ True, True, True, False], dtype=bool)
물론이 것 또한 작품의 당신은 얼마나입니다, 대신 별도의 배열 된 사실 중 하나 다차원 배열이있는 경우 의미 사용할 수 :
>>> xyz = np.array((x, y, z))
>>> xyz
array([[ True, True, False, False],
[ True, False, True, False],
[False, False, False, False]], dtype=bool)
>>> np.logical_or.reduce(xyz)
array([ True, True, True, False], dtype=bool)
그러나 3 개의 동일한 길이 1D 배열의 튜플은 NumPy 용어 로 array_like 이며 2D 배열로 사용할 수 있습니다.
NumPy 외부에서 Python의 reduce
다음을 사용할 수도 있습니다 .
>>> functools.reduce(np.logical_or, (x, y, z))
array([ True, True, True, False], dtype=bool)
그러나 NumPy와 달리 reduce
Python은 자주 필요하지 않습니다. 대부분의 경우, 체인, 것들 – 예를 들어 함께 여러 파이썬 할 수있는 간단한 방법이 or
연산자를하지 않는 reduce
이상 operator.or_
, 그냥 사용 any
. 그리고 가 없으면 명시 적 루프를 사용하는 것이 일반적으로 더 읽기 쉽습니다.
사실 NumPy any
는이 경우에도 사용할 수 있습니다. 축을 명시 적으로 지정하지 않으면 배열 대신 스칼라로 끝납니다. 그래서:
>>> np.any((x, y, z), axis=0)
array([ True, True, True, False], dtype=bool)
예상 할 수 있듯이, logical_and
비슷한 당신은 그것을 체인 수 np.reduce
그것, functools.reduce
그것을, 또는 대신 all
명시 적으로 axis
.
같은 다른 작업은 logical_xor
어떻습니까? 다시, 동일한 거래…이 경우 적용되는 all
/ any
유형 기능 이 없다는 점만 제외하면 . (무엇이라고 부르겠습니까 odd
??)
답변
세 개의 부울 배열을 가지고 말 – 경우 누군가가 여전히 필요 a
, b
, c
같은 모양으로,이 제공 and
: 요소 현명한
a * b * c
이것은 제공합니다 or
:
a + b + c
이것이 당신이 원하는 것입니까? 많이 쌓 logical_and
거나 logical_or
실용적이지 않습니다.
답변
부울 대수는 정의에 따라 교환 및 연관성이 있으므로 다음 문 은 a, b 및 c의 부울 값에 대해 동일합니다 .
a or b or c
(a or b) or c
a or (b or c)
(b or a) or c
따라서 이원적인 “logical_or”가 있고 세 개의 인수 (a, b 및 c)를 전달해야하는 경우 다음을 호출 할 수 있습니다.
logical_or(logical_or(a, b), c)
logical_or(a, logical_or(b, c))
logical_or(c, logical_or(b, a))
또는 원하는 순열.
파이썬으로 돌아가서 조건 (테스트 대상 test
을 취하고 부울 값을 반환하는 함수에 의해 생성됨)이 a, b 또는 c 또는 목록 L의 요소에 적용 되는지 테스트 하려면 일반적으로 사용합니다.
any(test(x) for x in L)
답변
n 차원 사례에 대한 abarnert의 답변을 기반으로 작성 :
TL; DR : np.logical_or.reduce(np.array(list))
답변
sum 함수 사용 :
a = np.array([True, False, True])
b = array([ False, False, True])
c = np.vstack([a,b,b])
Out[172]:
array([[ True, False, True],
[False, False, True],
[False, False, True]], dtype=bool)
np.sum(c,axis=0)>0
Out[173]: array([ True, False, True], dtype=bool)
답변
n 배열로 확장 할 수있는이 해결 방법을 사용합니다.
>>> a = np.array([False, True, False, False])
>>> b = np.array([True, False, False, False])
>>> c = np.array([False, False, False, True])
>>> d = (a + b + c > 0) # That's an "or" between multiple arrays
>>> d
array([ True, True, False, True], dtype=bool)
답변
다음 세 가지 방법을 시도하여 n 크기 의 k 배열 logical_and
목록 l 을 가져 왔습니다 .
- 재귀 사용
numpy.logical_and
(아래 참조) - 사용
numpy.logical_and.reduce(l)
- 사용
numpy.vstack(l).all(axis=0)
그런 다음 logical_or
기능에 대해서도 똑같이했습니다 . 놀랍게도 재귀 방법이 가장 빠릅니다.
import numpy
import perfplot
def and_recursive(*l):
if len(l) == 1:
return l[0].astype(bool)
elif len(l) == 2:
return numpy.logical_and(l[0],l[1])
elif len(l) > 2:
return and_recursive(and_recursive(*l[:2]),and_recursive(*l[2:]))
def or_recursive(*l):
if len(l) == 1:
return l[0].astype(bool)
elif len(l) == 2:
return numpy.logical_or(l[0],l[1])
elif len(l) > 2:
return or_recursive(or_recursive(*l[:2]),or_recursive(*l[2:]))
def and_reduce(*l):
return numpy.logical_and.reduce(l)
def or_reduce(*l):
return numpy.logical_or.reduce(l)
def and_stack(*l):
return numpy.vstack(l).all(axis=0)
def or_stack(*l):
return numpy.vstack(l).any(axis=0)
k = 10 # number of arrays to be combined
perfplot.plot(
setup=lambda n: [numpy.random.choice(a=[False, True], size=n) for j in range(k)],
kernels=[
lambda l: and_recursive(*l),
lambda l: and_reduce(*l),
lambda l: and_stack(*l),
lambda l: or_recursive(*l),
lambda l: or_reduce(*l),
lambda l: or_stack(*l),
],
labels = ['and_recursive', 'and_reduce', 'and_stack', 'or_recursive', 'or_reduce', 'or_stack'],
n_range=[2 ** j for j in range(20)],
logx=True,
logy=True,
xlabel="len(a)",
equality_check=None
)
여기에 k = 4의 공연이 있습니다.
그리고 여기 k = 10의 공연 아래.
더 높은 n에 대해서도 거의 일정한 시간 오버 헤드가있는 것 같습니다.