2014-03-13 2 views
2

다음 for 루프를 numpy로 밀어 넣으면 더 빠르게 처리 할 수 ​​있습니까? 로for 루프를 numpy로 푸시

bestepsilons = numpy.zeros((R.shape[0])) 
for i in range(R.shape[0]): 
    bestindex = numpy.nanargmin(R[i,:]) 
    if(numpy.isnan(bestindex)): 
     bestepsilons[i]=numpy.nan 
    else: 
     bestepsilons[i]=epsilon[bestindex] 

과 (혼자) 해결되었다 : 지금

bestepsilons1 = numpy.zeros(R.shape[0])+numpy.nan 
d0 = numpy.nanmin(R, axis=1) # places where the best index is not a nan 
bestepsilons1[~numpy.isnan(d0)] = epsilon[numpy.nanargmin(R[~numpy.isnan(d0),:], axis=1)] 

그러나 더

ri = numpy.zeros((R.shape[0],R.shape[2])) 
for i in range(R.shape[0]): 
    ri[i, :] = R[i, indices[i], :] 

이이 비트 속도를했다 내 이전 질문 making numpy.nanargmin return nan if column is all nan에 관한 복잡한 경우 :

bestepsilons = numpy.zeros((R.shape[0])) 
for i in range(R.shape[0]): 
    bestindex = numpy.nanargmin(R[i,indices[i],:]) 
    if(numpy.isnan(bestindex)): 
     bestepsilons[i]=numpy.nan 
    else: 
     bestepsilons[i]=epsilon[bestindex] 

그리고 지금이 트릭은 그 인덱스가 더 이상 작동하지 않는 최고의 인덱스가 아닌 장소를 보여줍니다.

답변

0

이 빠르게 약 10 %임을 찾았

d1 = numpy.arange(R.shape[0])[:,None] 
d2 = indices[numpy.arange(R.shape[0])][:,None] 
d3 = numpy.arange(R.shape[2])[None,:] 
ri = R[d1,d2,d3] 

bestepsilons = numpy.zeros(R.shape[0])+numpy.nan 
d0 = numpy.nanmin(ri, axis=1) # places where the best index is not a nan 
bestepsilons[~numpy.isnan(d0)] = epsilon[numpy.nanargmin(ri[~numpy.isnan(d0),:], axis=1)] 

하지만이 정의 R 함께 :

R = (self.VVm[:,None,None]-VVs[None,:,:])**2 + (self.HHm[:,None,None]-HHs[None,:,:])**2 

그리고 내가 R을 정의하면 다르게 거대한 용지를 더 줄일 수 있다는 사실을 발견 :

ti = indices[numpy.arange(len(VVm))] 
R1 = (VVm[:,None]-VVs[ti,:])**2+(HHm[:,None]-HHs[ti,:])**2 
d0 = numpy.nanmin(R1, axis=1) # places where the best index is not a nan 
bestepsilons2[~numpy.isnan(d0)] = epsilon[numpy.nanargmin(R1[~numpy.isnan(d0),:], axis=1)] 

그것은 3D R을해야하지만, (4 배의 속도 향상을 얻을 수)

차원에서 직접하게하지 않습니다이 방법
0

numpy로 밀어 넣을 수는 있지만 속도가 빠른지 여부는 배열의 크기에 따라 다릅니다. 바라 건데, 좀 더 우아한 해결책이있다, 그러나 이것은 작동합니다

def f1(R, indices): 
    ri = numpy.zeros((R.shape[0],R.shape[2])) 
    for i in range(R.shape[0]): 
     ri[i, :] = R[i, indices[i], :] 
    return ri 

def f2(R, indices): 
    ii = np.arange(R.shape[0]) * R.shape[1] + indices 
    return R.reshape(-1, R.shape[2])[ii] 

작은 R :

In [25]: R = np.random.rand(30, 40, 50) 
In [26]: indices = np.random.choice(range(R.shape[1]), R.shape[0], replace=True) 
In [27]: %timeit(f1(R, indices)) 
10000 loops, best of 3: 61.4 us per loop 
In [28]: %timeit(f2(R, indices)) 
10000 loops, best of 3: 21.9 us per loop 

R :

다음
ii = np.arange(R.shape[0]) * R.shape[1] + indices 
ri = R.reshape(-1, R.shape[2])[ii] 

는 몇 타이밍 시험이다
In [29]: R = np.random.rand(300, 400, 500) 
In [30]: indices = np.random.choice(range(R.shape[1]), R.shape[0], replace=True) 
In [31]: %timeit(f1(R, indices)) 
1000 loops, best of 3: 713 us per loop 
In [32]: %timeit(f2(R, indices)) 
1000 loops, best of 3: 1.23 ms per loop 

In [33]: np.all(f1(R, indices) == f2(R, indices)) 
Out[33]: True