2014-02-06 148 views
6

設L的關鍵部分是一個列表L = [A_1, A_2, ..., A_n],並且每個A_i的長度是1024用Cython優化numpy的陣列求和

numpy.int32陣列(大多數時間1000 <Ñ< 4000)。

一些剖析後,我看到了一個最耗時的操作是求和:

def summation(): 
    # L is a global variable, modified outside of this function 
    b = numpy.zeros(1024, numpy.int32) 
    for a in L: 
     b += a 
    return b 

PS:我不認爲我可以定義大小1024 x n的二維數組,因爲n不固定:某些元素被動態刪除/添加到L,所以len(L) = n在運行時間內可以在1000到4000之間變化。

我可以通過使用Cython獲得重大改進嗎? 如果是這樣,我應該怎麼用Cython,重新編碼,這個小功能(我不應該添加一些cdef打字?)

或者,你可以看到一些可能的其他方面的改進?

回答

2

這裏是用Cython代碼,確保以L每個數組C_CONTIGUOUS:

import cython 
import numpy as np 
cimport numpy as np 

@cython.boundscheck(False) 
@cython.wraparound(False) 
def sum_list(list a): 
    cdef int* x 
    cdef int* b 
    cdef int i, j 
    cdef int count 
    count = len(a[0]) 
    res = np.zeros_like(a[0]) 
    b = <int *>((<np.ndarray>res).data) 
    for j in range(len(a)): 
     x = <int *>((<np.ndarray>a[j]).data) 
     for i in range(count): 
      b[i] += x[i] 
    return res 

我的一個電腦是大約快4倍。

+0

非常感謝!這對我幫助很大 !你知道我如何修改這段代碼,如果[0],a [1]等是'int16 numpy arrays',並且我希望結果'res'仍然是'int32 numpy數組'嗎? – Basj

+0

如果輸入數組是'int16',並且輸出仍然是'int32',我用'cdef short * x'和'x = (( a [j])替換了'cdef int * x'。data)'由''。你認爲這是最好的方式嗎? – Basj