2017-07-06 62 views
0

當我在Cython中將一個numpy ndarray從一種類型轉換爲另一種類型時,出現非常奇怪的錯誤。例如,當我寫了下面的convert_test.pyx:Cython無法將float ndarray轉換爲int ndarray

cimport cython 
import numpy as np 
cimport numpy as np 

DTYPE = np.float32 
ctypedef np.float32_t DTYPE_t 

def convert_to_int(np.ndarray[DTYPE_t, ndim=2] float_matrix): 
    cdef np.ndarray[np.int, ndim=2] int_matrix=float_matrix.astype(np.int) 
    return int_matrix 

編譯和測試:

from convert_test import convert_to_int 
a_int=convert_to_int(np.zeros((2,2)).astype(np.float32)) 

我非常熟悉的消息:

ValueError異常:緩衝區D型不匹配,預計「 int object'but'long'

這可能是非常明顯的,但我還沒有看到它。

+0

Python 3沒有'int'類型。它已被實施爲「長」。所以,也許你應該轉換爲'long'而不是'int'。雖然,我沒有Cython的使用經驗,所以我不能說它會起作用。 – xyres

+0

我正在使用python2,但也許你正在做些什麼。 – jean

+0

@jean看到我的回答這個作品在Cython中製作不同類型的記憶體。如果你真的想要ndarray格式,我可以爲你寫出來,但如果你比較我的第二個樣本和第一個樣本,它應該是非常直觀的。還要注意,只是從一個單一的轉換爲一個整數,它會截斷小數點(不捨入),所以這個函數可能不是你打算做的...... – Matt

回答

0

爲什麼你不這樣做?編譯和工作得很好我的電腦上:

cimport cython 
import numpy as np 
cimport numpy as np 

DTYPE = np.float32 
ctypedef np.float32_t DTYPE_t 

def convert_to_int(np.ndarray[DTYPE_t, ndim=2] float_matrix): 
    int_matrix = np.array(float_matrix, dtype=np.int32) 
    return int_matrix 

或者,如果你真的想要一個memoryview:

def convert_to_int(DTYPE_t[:,:] float_matrix): 
    cdef int[:,:] int_matrix = np.array(float_matrix, dtype=np.int32) 
    return np.asarray(int_matrix) 

第二個答案我只是轉換舊ndarray參數,以現代typed memoryviews語法int_matrixfloat_matrix 。上面的樣式是矩陣的連續內存格式[:,:](比如NumPy默認使用numpy.zeros)。

請注意,您發佈的功能僅僅是將截斷小數點後的一切(不四捨五入向上/向下),所以可以肯定這是你的原意。

0

您必須在聲明中使用_t類型:cdef np.ndarray [np.int_t,ndim = 2]。