2013-09-04 11 views
6

스크립트를 작성하는 동안 numpy.random.choice 기능을 발견했습니다. 동일한 if 문보다 훨씬 깔끔하기 때문에 구현했습니다. 그러나 스크립트를 실행 한 후에는 인데, if 문보다 느리게입니다.random.choice가 왜 그렇게 느린가요?

다음은 MWE입니다. 첫 번째 방법은 0.0 초, 두 번째 방법은 7.2 초가 소요됩니다. i 루프를 확장하면 random.choice가 얼마나 빨리 속도가 느려지는지 알 수 있습니다.

누구든지 random.choice가 왜 그렇게 느린 지에 대해 의견을 말할 수 있습니까?

import numpy as np 
import numpy.random as rand 
import time as tm 

#------------------------------------------------------------------------------- 

tStart = tm.time() 
for i in xrange(100): 
    for j in xrange(1000): 
     tmp = rand.rand() 
     if tmp < 0.25: 
      var = 1 
     elif tmp < 0.5: 
      var = -1 
print('Time: %.1f s' %(tm.time() - tStart)) 

#------------------------------------------------------------------------------- 

tStart = tm.time() 
for i in xrange(100): 
    for j in xrange(1000): 
     var = rand.choice([-1, 0, 1], p = [0.25, 0.5, 0.25]) 
print('Time: %.1f s' %(tm.time() - tStart)) 
+3

그건 정말 공정한 비교가 아닙니다. 매번 numpy는 p 목록의 누적 합계를 가져와 새 벡터에 넣은 다음 반복합니다. 세 개의 변수 만 있고 첫 번째와 세 번째의 합이 .5라는 사실을 알면 효과적으로 사전 처리를 수행 할 수 있습니다. 그 외에도 numpy는 벡터화 된 연산에 최적화되어 있으며 수천 번의 단일 연산 만 수행하는 것이 아닙니다. –

+1

또한 'timeit'을 사용하지 말고'time'을 사용하십시오. – Marcin

답변

12

잘못 사용하고 있습니다. 작업을 벡터화, 또는 NumPy와는 아무런 혜택을 제공하지 않습니다 :

var = numpy.random.choice([-1, 0, 1], size=1000, p=[0.25, 0.5, 0.25]) 

타이밍 데이터 :

>>> timeit.timeit('''numpy.random.choice([-1, 0, 1], 
...          size=1000, 
...          p=[0.25, 0.5, 0.25])''', 
...    'import numpy', number=10000) 
2.380380242513752 

>>> timeit.timeit(''' 
... var = [] 
... for i in xrange(1000): 
...  tmp = rand.rand() 
...  if tmp < 0.25: 
...   var.append(1) 
...  elif tmp < 0.5: 
...   var.append(-1) 
...  else: 
...   var.append(0)''', 
... setup='import numpy.random as rand', number=10000) 
5.673041396894519 
+2

+1 첫 번째 루프보다 약 7 배 빠릅니다. –

+0

서면으로 사과와 사과를 비교하고 있습니까? 첫 번째 것은 10^3 * 10^4 = 10^7 난수를 계산하지만 두 번째는 10^2 * 10^3 * 10^4 = 10^9 난수를 계산합니다. – DSM

+0

@DSM : 오발. 시간에 잘못된 것을 복사했습니다. 수정 중 ... – user2357112

1

내가 np.random.choice의 일반성이 큰 것보다 작은 샘플에 대한 더 많은 그래서, 그것을 아래로 둔화되고 생각한다.

if 버전의 원유 벡터화은 다음과 같습니다

ipython에서 실행
def foo(n): 
    x = np.random.rand(n) 
    var = np.zeros(n) 
    var[x<.25] = -1 
    var[x>.75] = 1 
    return var 

내가 얻을 :

timeit np.random.choice([-1,0,1],size=1000,p=[.25,.5,.25]) 
1000 loops, best of 3: 293 us per loop 

timeit foo(1000) 
10000 loops, best of 3: 83.4 us per loop 

timeit np.random.choice([-1,0,1],size=100000,p=[.25,.5,.25]) 
100 loops, best of 3: 11 ms per loop 

timeit foo(100000) 
100 loops, best of 3: 8.12 ms per loop 

는 그래서 1000 크기, choice는하지만 큰 벡터와, 느린 3-4 배입니다 차이가 사라지기 시작합니다.

관련 문제