2016-07-05 9 views
7

문제 :최적화 배열 요소 쉬프트 파이썬/NumPy와

내가 작성한 데이터 분석 코드의 라인 프로파일 링을 실행 한 후, 나는 전체 실행 시간의 약 70 %가 호출에 집중되어 있음을 발견했다 2 개의 다른 배열 조작 루틴. 결국 실시간 방식으로 데이터를 분석하기를 원할 것입니다. 따라서 여기의 최적화가 크게 도움이 될 것입니다.

Matrix Forms

두 기능은 좌측의 행렬을 오른쪽 (또는 그 반대)의 형태로 가져온다.

관심있는 행렬은 현재 N × N 개의 numpy 배열 (N은 짝수)로 저장됩니다.

코드 :이 작업을 수행하려면 다음 코드를 작성했습니다

: 원래이를 작성할 때 내가 NumPy와의 롤 기능을 인식하지 못하는, 그래서 내가있는 vec_shift 기능을 작성했다

# Shifts elements of a vector to the left by the given amount. 
def Vec_shift_L(vec, shift=0): 
    s = vec.size 
    out = np.zeros(s, dtype=complex) 
    out[:s-shift] = vec[shift:] 
    out[s-shift:] = vec[:shift] 
    return out 

# Shifts elements of a vector to the right by the given amount. 
def Vec_shift_R(vec,shift=0): 
    s=vec.size 
    out=np.zeros(s, dtype=complex) 
    out[:shift] = vec[s-shift:] 
    out[shift:] = vec[:s-shift] 
    return out 

# Shifts a matrix from the left form (above) to the right form. 
def OP_Shift(Trace): 
    s = Trace.shape 
    Out = np.zeros(s, dtype=complex) 

    for i in np.arange(s[0]): 
     Out[i,:] = Vec_shift_L(Trace[i,:], (i+s[0]/2) % s[0]) 

    for i in np.arange(s[0]): 
     Out[i,:] = np.flipud(Out[i,:]) 

    return Out 

# Shifts a matrix from the right form (above) to the left form. 
def iOP_Shift(Trace): 
    s = Trace.shape 
    Out = np.zeros(s, dtype=complex) 
    for i in np.arange(s[0]): 
     Out[i,:] = np.flipud(Trace[i,:]) 

    for i in np.arange(s[0]): 
     Out[i,:] = Vec_shift_R(Out[i,:], (i+s[0]/2) % s[0]) 

    return Out 

의 장소. 현재 시스템에서 롤을 사용하는 것보다 성능이 30 % 이상 향상 된 것 같습니다.

이 코드의 성능을 더욱 향상시킬 수있는 방법이 있습니까?

답변

5

벡터화 된 솔루션으로 NumPy broadcasting을 도와주세요!

# Store shape of input array 
s = Trace.shape 

# Store arrays corresponding to row and column indices 
I = np.arange(s[0]) 
J = np.arange(s[1]-1,-1,-1) 

# Store all iterating values in "(i+s[0]/2) % s[0]" as an array 
shifts = (I + s[0]/2)%s[0] 

# Calculate all 2D linear indices corresponding to 2D transformed array 
linear_idx = (((shifts[:,None] + J)%s[1]) + I[:,None]*s[1]) 

# Finally index into input array with indices for final output 
out = np.take(Trace,linear_idx) 
+0

감사합니다. 이와 같이 우아한 방식으로 호환되지 않는 행렬 모양에 대한 작업을 수행 할 수 있다는 것을 알지 못했습니다. 이것은 상당히 도움이됩니다. :디 – DMilden