주어진 조건의 배열 요소를 어떻게 선택합니까?


156

내가 NumPy와 배열을 가정 x = [5, 2, 3, 1, 4, 5], y = ['f', 'o', 'o', 'b', 'a', 'r']. 1보다 크고 5보다 작은 요소에 y해당하는 요소를 선택하고 싶습니다 x.

나는 시도했다

x = array([5, 2, 3, 1, 4, 5])
y = array(['f','o','o','b','a','r'])
output = y[x > 1 & x < 5] # desired output is ['o','o','a']

그러나 이것은 작동하지 않습니다. 어떻게해야합니까?

답변:


220

괄호를 추가하면 표현식이 작동합니다.

>>> y[(1 < x) & (x < 5)]
array(['o', 'o', 'a'], 
      dtype='|S1')

1
vecMask = 1 <x는 vecMask = (False, True, ...)와 같은 벡터 마스크를 생성하며 다른 벡터 마스크와 결합 될 수 있습니다. 각 요소는 소스 벡터의 요소를 가져 오기위한 조건 (True) 또는 아닙니다 (False). 정식 버전 numpy.extract (vecMask, vecSrc) 또는 numpy.where (vecMask, vecSrc, vecSrc2)와 함께 사용할 수도 있습니다.
MasterControlProgram

6
@JennyYueJin : 우선 순위 때문에 발생합니다. (Bitwise) &<and 보다 우선 순위가 높으며 >, 이는 (logical)보다 우선 순위가 높습니다 and. x > 1 and x < 5불평등을 먼저 완화 한 다음 논리적 연결을 제거합니다. x > 1 & x < 5비트 단위의 결합을 평가 1하고 (의 값) x이어서, 부등식. (x > 1) & (x < 5)불평등이 먼저 평가되도록하여 모든 연산이 의도 한 순서대로 발생하고 결과가 모두 명확하게 정의됩니다. 여기 문서를 참조하십시오.
calavicci

@ ru111 파이썬 3.6에서도 작동합니다 (작동을 멈출 이유가 없습니다).
jfs

"ValueError : 하나 이상의 요소를 가진 배열의 실제 값이 모호합니다. a.any () 또는 a.all () 사용"
ru111

@ ru111은 파이썬 버전의 numpy 배열에서 작동하지 않는 (0 < x) & (x < 10)대신 (답변에 표시된대로) 작성해야합니다 0 < x < 10.
jfs

34

IMO 영업 이익은 실제로 원하지 않는다 np.bitwise_and()(일명 &) 실제로 원하는 np.logical_and()그들과 같은 논리 값 비교되기 때문에 TrueFalse-에 SO 게시물을 참조 비트 대 논리적 차이를 볼 수 있습니다.

>>> x = array([5, 2, 3, 1, 4, 5])
>>> y = array(['f','o','o','b','a','r'])
>>> output = y[np.logical_and(x > 1, x < 5)] # desired output is ['o','o','a']
>>> output
array(['o', 'o', 'a'],
      dtype='|S1')

이와 동등한 방법 np.all()axis인수를 적절하게 설정하는 것 입니다.

>>> output = y[np.all([x > 1, x < 5], axis=0)] # desired output is ['o','o','a']
>>> output
array(['o', 'o', 'a'],
      dtype='|S1')

숫자로 :

>>> %timeit (a < b) & (b < c)
The slowest run took 32.97 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 1.15 µs per loop

>>> %timeit np.logical_and(a < b, b < c)
The slowest run took 32.59 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 1.17 µs per loop

>>> %timeit np.all([a < b, b < c], 0)
The slowest run took 67.47 times longer than the fastest. This could mean that an intermediate result is being cached.
100000 loops, best of 3: 5.06 µs per loop

그래서 사용은 np.all()느리지 만 &logical_and거의 동일하다.


7
평가 대상에 대해 어떻게 말하는지 신중해야합니다. 예를 들어 in 평가가 함수 외부에서 발생하기 때문에 두 번째 인수이지만 in output = y[np.logical_and(x > 1, x < 5)]에서 평가됩니다 (거대한 배열을 생성 할 수 있음). IOW 는 이미 평가 된 두 개의 인수를 전달받습니다. 이것은 일반적인 경우와 다르며 , 사실과 같은지 평가되지 않습니다 . x < 5 logical_anda and bba
DSM

15
부울 배열의 경우 bitwise_and ()와 logical_and () 사이에는 차이가 없습니다.
jfs

21

@JF Sebastian과 @Mark Mikofski의 답변에 세부 사항을 추가하십시오 :
실제 배열 값이 아닌 해당 인덱스를 얻으려면 다음 코드가 수행됩니다.

여러 (모든) 조건을 만족시키는 경우 :

select_indices = np.where( np.logical_and( x > 1, x < 5) )[0] #   1 < x <5

여러 조건을 만족시키는 경우 :

select_indices = np.where( np.logical_or( x < 1, x > 5 ) )[0] # x <1 or x >5

2
바로 인덱스의 배열을 반환하지 않을 것이다 numpy.where 참고, 대신 튜플 돌아갑니다 (condition.nonzero의 출력을 ()) 배열을 포함하는 -이 경우하면 (the array of indices you want,), 당신은해야합니다, 그래서 select_indices = np.where(...)[0]당신이 원하는 결과를 얻을 수 그리고 기대하십시오.
calavicci

5

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

>>> # Arrays
>>> x = np.array([5, 2, 3, 1, 4, 5])
>>> y = np.array(['f','o','o','b','a','r'])

>>> # Function containing the constraints
>>> func = np.vectorize(lambda t: t>1 and t<5)

>>> # Call function on x
>>> y[func(x)]
>>> array(['o', 'o', 'a'], dtype='<U1')

벡터화 된 함수에 더 많은 유형의 구속 조건을 추가 할 수 있다는 장점이 있습니다.

도움이 되길 바랍니다.


1
이것은 NumPy에서 인덱싱을 수행하는 좋은 방법이 아닙니다 (매우 느릴 것입니다).
Alex Riley

1

실제로 나는 이렇게 할 것입니다 :

L1은 조건 1을 만족하는 요소의 색인 목록입니다. ( L1을 사용 somelist.index(condition1)하거나 np.where(condition1)얻을 수 있습니다 .)

마찬가지로 조건 2를 만족하는 요소 목록 인 L2를 얻습니다.

그런 다음을 사용하여 교차점을 찾습니다 intersect(L1,L2).

여러 조건을 만족하는 경우 여러 목록의 교차를 찾을 수도 있습니다.

그런 다음 다른 배열 (예 : x)에 색인을 적용 할 수 있습니다.


0

2D 배열의 경우이 작업을 수행 할 수 있습니다. 조건을 사용하여 2D 마스크를 만듭니다. 배열에 따라 조건 마스크를 int 또는 float로 typecast하고 원래 배열과 곱하십시오.

In [8]: arr
Out[8]: 
array([[ 1.,  2.,  3.,  4.,  5.],
       [ 6.,  7.,  8.,  9., 10.]])

In [9]: arr*(arr % 2 == 0).astype(np.int) 
Out[9]: 
array([[ 0.,  2.,  0.,  4.,  0.],
       [ 6.,  0.,  8.,  0., 10.]])
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.