2016-10-13 4 views
2

저는 최적화 방법에 대해 생각할 때 아직 애착이 있습니다. 발견 된 봉우리 목록을 가져 와서 이러한 봉우리가 어느 정도 가치가있는 부분을 다차원 배열에 배치하는 코드 섹션이 있습니다. 그런 다음 0을 0으로 색인에 +1합니다. 코드는 잘 작동하지만 실행하는 데 시간이 오래 걸립니다. 예를 들어 ind의 값이 270이고 refVals의 모양이 (3050,3130,80) 인 경우 실행하는 데 45 분이 걸립니다. 나는 그 많은 데이터가 휘젓다는 것을 이해한다. 그러나 이것에 관해서 더 효율적인 방법이 있는가?Numpy Masking의 속도 향상

maskData = np.zeros_like(refVals).astype(np.int16) 

for peak in ind: 
     tmpArr = np.ma.masked_outside(refVals,x[peak]-2,x[peak]+2).astype(np.int16) 
     maskData[tmpArr.mask == False ] += 1 
     tmpArr = None 

maskData = np.sum(maskData,axis=2) 

답변

2

접근 # 1 : 메모리가 허용 여기 broadcasting 사용하여 벡터화 된 접근 방식 -

# Craate +,-2 limits usind ind 
r = x[ind[:,None]] + [-2,2] 

# Use limits to get inside matches and sum over the iterative and last dim 
mask = (refVals >= r[:,None,None,None,0]) & (refVals <= r[:,None,None,None,1]) 
out = mask.sum(axis=(0,3)) 

접근 방법 # 2 : 이전에 메모리가 부족하면, 우리 루프를 사용하고 NumPy 부울 배열을 사용할 수 있으므로 마스크 배열보다 더 효율적일 수 있습니다. 또한 우리는 sum-reduction 레벨을 한 번 더 수행 할 것이므로 반복을 가로 질러 움직일 때 우리와 함께 데이터를 끌어 들이지 않을 것입니다. 따라서, 다른 구현이이 같은 보일 것이다 -

out = np.zeros(refVals.shape[:2]).astype(np.int16) 
x_ind = x[ind] 
for i in x_ind: 
    out += ((refVals >= i-2) & (refVals <= i+2)).sum(-1) 

접근 # 3 : 다른 방법을, 우리는 접근 # 2 np.isclose와 그 한계를 기반으로 비교를 대체 할 수있다. 따라서 루프 내부의 유일한 단계는 다음과 같이됩니다. -

out += np.isclose(refVals,i,atol=2).sum(-1) 
+0

접근 방식 # 1은 즉시 내 메모리를 지 웁니다. 그러나 그렇지 않으면 좋았을 것입니다. # 2와 # 3은 훌륭하게 작동합니다. 급격한 개선이 있습니다. 감사 – nanoPhD