2016-07-14 3 views
4

0에서 1 사이의 값 배열 인 r이 있다고 가정 해 봅시다. 중간 값에서 일부 임계 값 인 모든 값을 제거하려고합니다. 여기서 임계 값은 0.5이고 len(r) = 3000이라고 가정합시다. 그런 다음이 범위를 벗어나는 모든 값을 마스크, 나는 내가 좋아하는 간단한 목록 이해, 수행 할 수NumPy에서이 비단뱀 목록 이해를 어떻게 할 수 있습니까?

import time 
import numpy as np 

start = time.time() 
r = np.random.random(3000) 
m = np.median(r) 
maxr,minr = m-0.5, m+0.5 
mask = [ri<minr or ri>maxr for ri in r] 
end = time.time() 
print('Took %.4f seconds'%(end-start)) 

>>> Took 0.0010 seconds

:

mask = np.array([ri < np.median(r)-0.5 or ri > np.median(r)+0.5 for ri in r])

을 그리고를 난에 타이머를 사용하는 경우

이 목록 이해를 수행하고 NumPy을 사용하여 마스크를 만드는 더 빠른 방법이 있습니까?


편집 : 포함, 아래에 몇 가지 제안을 시도했습니다

:

  • 의 요소 현명한 또는 운영자 : (r<minv) | (r>maxv)

  • NumPy와 논리적 또는 : r[np.logical_or(r<minr, r>maxr)]

  • 절대 차이 부울 배열 : 당신의 elementwise을 볼 수 있듯이

    Python list comprehension: 0.6511 ms 
    Elementwise or: 0.0138 ms 
    Numpy logical or: 0.0241 ms 
    Absolute difference: 0.0248 ms 
    

    또는 항상 빠른했다 : 여기 abs(m-r) > 0.5

그리고 각 하나를 통해 (300)가 실행 된 이후에 걸린 평균 시간입니다 거의 2 배 정도 (배열 요소로 어떻게 확장하는지) 알 수 없습니다. 누가 알았 겠어.

+0

'[리 <-maxr'마이너스 여기 오타에 서명한다? – ayhan

+0

@ayhan yea 미안하지만, 최소값과 최대 값도 flood되었습니다. – Anonymous

+1

시도해보십시오. (r> maxr) | (r ayhan

답변

3

numpy 조건부 선택을 사용하여 해당 값없이 새 배열을 만들 수 있습니다.

start = time.time() 
m = np.median(r) 
maxr,minr = m-0.5, m+0.5 
filtered_array = r[ (r < minr) | (r > maxr) ] 
end = time.time() 
print('Took %.4f seconds'%(end-start)) 

filtered_array는 마스크 값 (이후 이미 filtered_array 제거 마스크로 제거되는 모든 값)없이 r의 조각이다.

업데이트 : @ayhan이 제안한 짧은 구문이 사용되었습니다.

+0

가장 빠르고 감사합니다. 'np.logical_or()'를 사용한 원래 응답이 느리지 만. – Anonymous

3

하나 라이너 ...

new_mask = abs(np.median(r) - r) > 0.5 
+0

훌륭하고 간결하지만 가장 빠르지는 않습니다. 편집을 참조하십시오. – Anonymous

+0

배포판의 꼬리가 필요할 때 매우 유용합니다. 나는 선명도가 좋아. –