2016-07-05 4 views
7

Проблема:Оптимизация массива элементов Перемена в Python/Numpy

После запуска линии профилирования кода анализа данных я написал, я обнаружил, что около 70% от общего времени выполнения концентрируется в вызовах две различные манипуляции с массивами. В конечном итоге я бы хотел проанализировать данные в режиме реального времени, поэтому любая оптимизация здесь поможет значительно.

Matrix Forms

Обе функции принимают матрицу слева и привести его в форму на правой (и наоборот).

Матрицы, которые меня интересуют, в настоящее время хранятся как массивы N на N 2d numpy (где N равно).

Код:

Я написал следующий код для достижения этой цели:

# 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 

Я не знал о функции рулонной Numpy, когда первоначально писал это, так что я написал функцию vec_shift в его место. Кажется, что они увеличивают производительность на 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

Спасибо! Я не знал, что вы можете выполнять операции с другими несовместимыми матричными формами таким элегантным способом, как это. Это значительно помогает. : D – DMilden

Смежные вопросы