2017-06-15 79 views
0

我正在測試基於第i個和第j個索引的總和是偶數還是奇數而改變numpy ndarray的Cython性能。與Python相比,Cython的速度僅僅提高了80%,這在速度上有點平庸。目前我已經沒有想法了。有什麼建議麼?使用Cython提高處理Numpy的速度ndarray

@Python:

def even_odd_function(matrix): 

    dim = matrix.shape[1] 

    for i in range(dim): 
     for j in range(dim): 
      if (i + j) % 2 == 0: 
       matrix[i, j] = matrix[i, j] ** 2 
      else: 
       matrix[i, j] = matrix[i, j] * -1 

    return matrix 

@Cython:

%%cython 

import numpy as np 
cimport numpy as np 
cimport cython 

DTYPE = np.int 
ctypedef np.int DTYPE_t 

@cython.boundscheck(False) 
@cython.wraparound(False) 
@cython.nonecheck(False) 
def even_odd_function7(np.ndarray matrix): 

    cdef int dim = matrix.shape[1] 
    cdef int i 
    cdef int j 

    for i in range(dim): 
     for j in range(dim): 
      if (i + j) % 2 == 0: 
       matrix[i, j] = matrix[i, j] * matrix[i, j] 
      else: 
       matrix[i, j] = matrix[i, j] * -1 

    return matrix 

這裏是高亮行: enter image description here

回答

4

您需要註釋你的陣列的類型主要的加速。

import numpy as np 
cimport numpy as np 
cimport cython 

@cython.boundscheck(False) 
@cython.wraparound(False) 
@cython.nonecheck(False) 
def even_odd_function8(np.ndarray[np.float64_t, ndim=2] matrix): 

    cdef int dim = matrix.shape[1] 
    cdef int i 
    cdef int j 

    for i in range(dim): 
     for j in range(dim): 
      if (i + j) % 2 == 0: 
       matrix[i, j] = matrix[i, j] * matrix[i, j] 
      else: 
       matrix[i, j] = matrix[i, j] * -1 

    return matrix 

In [20]: arr = np.random.randn(1000, 1000) 

In [21]: %timeit even_odd_function(arr) 
1 loop, best of 3: 636 ms per loop 

In [22]: %timeit even_odd_function7(arr) 
1 loop, best of 3: 480 ms per loop 

In [24]: %timeit even_odd_function8(arr) 
1000 loops, best of 3: 1.61 ms per loop 

很大程度上是一種文體的東西,但我更喜歡更新類型的memoryview語法,它會做同樣的事情。

def even_odd_function(np.float64_t[:,:] matrix) 
+0

謝謝你。有效。我不明白的唯一部分是ndim。這意味着什麼? – MLhacker

+0

'ndim' =數組中的維數,因此在這種情況下2.在內存視圖版本中,維數由空切片的數量來表示 - 'float64_t [:]'= 1 dim,'float64_t [: ,:''= 2 dim等。 – chrisb