[python] 기능이 여러 조건 인 Numpy

dists라는 거리 배열이 있습니다. 두 값 사이의 dists를 선택하고 싶습니다. 이를 위해 다음 코드 줄을 작성했습니다.

 dists[(np.where(dists >= r)) and (np.where(dists <= r + dr))]

그러나 이것은 조건에 대해서만 선택합니다

 (np.where(dists <= r + dr))

임시 변수를 사용하여 순차적으로 명령을 수행하면 정상적으로 작동합니다. 위의 코드가 작동하지 않는 이유는 무엇이며 어떻게 작동합니까?

건배



답변

특정 경우 에 가장 좋은 방법은 두 가지 기준을 하나의 기준으로 변경하는 것입니다.

dists[abs(dists - r - dr/2.) <= dr/2.]

그것은 하나 개의 부울 배열을 생성하고, 내 의견으로는, 그것이 말하는 때문에 쉽게 읽을 수 있다 dist내에서 dr또는 r? (하지만 r처음부터 관심 지역의 중심으로 재정의하고 싶지만 r = r + dr/2.) 그러나 귀하의 질문에 대답하지 않습니다.


귀하의 질문에 대한 답변 : 기준에 맞지 않는 요소를 필터링하려고하는 경우
실제로 필요 하지 않습니다.wheredists

dists[(dists >= r) & (dists <= r+dr)]

&는 요소별로 요소를 제공 하기 때문에 and(괄호가 필요합니다).

또는 where어떤 이유로 사용하려면 다음을 수행하십시오.

 dists[(np.where((dists >= r) & (dists <= r + dr)))]

이유 :
작동하지 않는 이유 np.where는 부울 배열이 아닌 인덱스 목록을 반환 하기 때문 입니다. and두 숫자 목록 사이 를 가져 오려고하는데 물론 True/ False값 이 없습니다 . 경우 ab모두 True값, 다음 a and b반환 b. 따라서 이와 같은 말 [0,1,2] and [2,3,4]은 당신에게 줄 것 [2,3,4]입니다. 여기 실제로 작동합니다.

In [230]: dists = np.arange(0,10,.5)
In [231]: r = 5
In [232]: dr = 1

In [233]: np.where(dists >= r)
Out[233]: (array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),)

In [234]: np.where(dists <= r+dr)
Out[234]: (array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12]),)

In [235]: np.where(dists >= r) and np.where(dists <= r+dr)
Out[235]: (array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12]),)

예를 들어 비교하려고 한 것은 단순히 부울 배열이었습니다.

In [236]: dists >= r
Out[236]:
array([False, False, False, False, False, False, False, False, False,
       False,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True], dtype=bool)

In [237]: dists <= r + dr
Out[237]:
array([ True,  True,  True,  True,  True,  True,  True,  True,  True,
        True,  True,  True,  True, False, False, False, False, False,
       False, False], dtype=bool)

In [238]: (dists >= r) & (dists <= r + dr)
Out[238]:
array([False, False, False, False, False, False, False, False, False,
       False,  True,  True,  True, False, False, False, False, False,
       False, False], dtype=bool)

이제 np.where결합 된 부울 배열을 호출 할 수 있습니다 .

In [239]: np.where((dists >= r) & (dists <= r + dr))
Out[239]: (array([10, 11, 12]),)

In [240]: dists[np.where((dists >= r) & (dists <= r + dr))]
Out[240]: array([ 5. ,  5.5,  6. ])

또는 멋진 색인 생성을 사용하여 원래 배열을 부울 배열로 색인화합니다.

In [241]: dists[(dists >= r) & (dists <= r + dr)]
Out[241]: array([ 5. ,  5.5,  6. ])


답변

받아 들여진 대답은 문제를 충분히 설명했습니다. 그러나 여러 조건을 적용하기위한 Numpythonic 방식이 많을수록 numpy 논리 함수 를 사용하는 입니다. 이 ase에서는 다음을 사용할 수 있습니다 np.logical_and.

np.where(np.logical_and(np.greater_equal(dists,r),np.greater_equal(dists,r + dr)))


답변

여기서 한 가지 흥미로운 점은 다음과 같습니다. 이 경우 ORAND 를 사용하는 일반적인 방법 도 작동하지만 약간의 변경이 있습니다. “and”대신 “or”대신 Ampersand (&)Pipe Operator (|) 를 사용하면 작동합니다.

‘and’를 사용할 때 :

ar = np.array([3,4,5,14,2,4,3,7])
np.where((ar>3) and (ar<6), 'yo', ar)

Output:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

앰퍼샌드 (&)를 사용할 때 :

ar = np.array([3,4,5,14,2,4,3,7])
np.where((ar>3) & (ar<6), 'yo', ar)

Output:
array(['3', 'yo', 'yo', '14', '2', 'yo', '3', '7'], dtype='<U11')

팬더 데이터 프레임의 경우 여러 필터를 적용하려고 할 때도 마찬가지입니다. 이제이 논리는 논리 연산자 및 비트 연산자와 관련이 있으며 그에 대한 더 많은 이해를 위해이 답변 또는 유사한 Q / A를 스택 오버 플로우로 진행하는 것이 좋습니다 .

최신 정보

사용자가 괄호 안에 (ar> 3) 및 (ar <6)을 제공해야하는 이유가 무엇인지 물었습니다. 여기에 문제가 있습니다. 여기서 무슨 일이 일어나고 있는지 이야기하기 전에 파이썬에서 연산자 우선 순위에 대해 알아야합니다.

BODMAS에 관한 것과 유사하게, 파이썬은 또한 먼저 수행해야 할 것에 우선권을줍니다. 괄호 안의 항목이 먼저 수행 된 다음 비트 연산자가 작동합니다. “(“, “)”를 사용하고 사용하지 않을 때 두 경우 모두에서 발생하는 상황을 아래에서 보여 드리겠습니다.

사례 1 :

np.where( ar>3 & ar<6, 'yo', ar)
np.where( np.array([3,4,5,14,2,4,3,7])>3 & np.array([3,4,5,14,2,4,3,7])<6, 'yo', ar)

더 괄호 여기가 없기 때문에, 비트 단위 연산자 ( &) 당신도 그것을 요구하는 어떤 논리적 얻을 것으로 여기 혼란스러워지고 AND 연산자 우선 순위 테이블에 당신이 볼 경우 때문에,의, &보다 우선 순위가 주어집니다 <또는 >운영자. 다음은 가장 낮은 우선 순위에서 가장 높은 우선 순위까지의 표입니다.

여기에 이미지 설명을 입력하십시오

심지어 <and >연산을 수행하지 않고 논리 AND 연산을 수행하라는 요청을 받고 있습니다. 그래서 그 오류가 발생합니다.

다음 링크를 확인하여 자세한 내용을 알아볼 수 있습니다. 연산자 우선 순위

이제 사례 2 :

대괄호를 사용하면 어떻게되는지 명확하게 알 수 있습니다.

np.where( (ar>3) & (ar<6), 'yo', ar)
np.where( (array([False,  True,  True,  True, False,  True, False,  True])) & (array([ True,  True,  True, False,  True,  True,  True, False])), 'yo', ar)

True와 False의 두 배열. 또한 논리적 AND 연산을 쉽게 수행 할 수 있습니다. 어느 것이 당신에게줍니다 :

np.where( array([False,  True,  True, False, False,  True, False, False]),  'yo', ar)

np.where는 주어진 경우에, True가 어디든지 첫 번째 값 (예 : ‘yo’)을 할당하고 False이면 다른 값 (예 : 여기에서 원본 유지)을 할당합니다.

그게 다야. 쿼리를 잘 설명했으면합니다.


답변

나는 np.vectorize그러한 작업 에 사용 하고 싶습니다 . 다음을 고려하세요:

>>> # function which returns True when constraints are satisfied.
>>> func = lambda d: d >= r and d<= (r+dr)
>>>
>>> # Apply constraints element-wise to the dists array.
>>> result = np.vectorize(func)(dists)
>>>
>>> result = np.where(result) # Get output.

선명한 출력 np.argwhere대신에 사용할 수도 있습니다 np.where. 그러나 그것은 당신의 전화입니다 🙂

도움이 되길 바랍니다.


답변

시험:

np.intersect1d(np.where(dists >= r)[0],np.where(dists <= r + dr)[0])


답변

이것은 작동해야합니다 :

dists[((dists >= r) & (dists <= r+dr))]

가장 우아한 방법 ~~


답변

시험:

import numpy as np
dist = np.array([1,2,3,4,5])
r = 2
dr = 3
np.where(np.logical_and(dist> r, dist<=r+dr))

출력 : (배열 ([2, 3]),)

자세한 내용 은 논리 기능 을 참조하십시오.