2015-08-28 16 views
7

Tôi gặp sự cố khi chuyển qua bộ nhớ này về các số nguyên vào hàm này (khá nhỏ). Python đang cung cấp cho tôi lỗi này:Cython: Loại bộ đệm không khớp, được mong đợi là 'int' nhưng có 'dài'

ValueError: Buffer dtype mismatch, expected 'int' but got 'long' 

Ai đó có thể giúp tôi hiểu điều gì đang xảy ra không? Tìm kiếm xung quanh stackoverflow, có vẻ như nó đã làm với cách python diễn giải các loại, và cách C diễn giải các loại.

%%cython 
def myfunction(int [:] y): 
    pass 

# Python code 
import numpy as np 
y = np.array([0, 0, 1, 1]) 
myfunction(y) 

Điều này tạo ra ValueError từ trên cao.

EDIT: Dưới đây là một số điều khác tôi đã khám phá.

Để làm rõ, lỗi này vẫn tồn nếu tôi tuyên bố y các cách sau:

y = np.array([0, 0, 1, 1], dtype='int') 
y = np.array([0, 0, 1, 1], dtype=np.int) 
y = np.array([0, 0, 1, 1], dtype=np.int64) 

Tuy nhiên, nó hoạt động nếu tôi tuyên bố y với

y = np.array([0, 0, 1, 1], dtype=np.int32) 

Có ai muốn đưa ra một gợi ý tại sao điều này là trường hợp? Việc ném vào np.int32 có hoạt động trên các máy tính khác nhau không? (Tôi sử dụng macbook pro retina, 2013.)

Trả lời

9

Bạn đang sử dụng loại int của Cython, chỉ là Cint. Tôi nghĩ rằng trên Mac (hoặc hầu hết các kiến ​​trúc) nó là int 32-bit. Xem wiki hoặc intel hoặc Does the size of an int depend on the compiler and/or processor?

Mặt khác, long có nghĩa là int64. dtype='int' hoặc dtype=np.int đều tương đương với np.int64.

Tôi nghĩ rằng bạn chỉ có thể xác định một cách rõ ràng nó là một trong những loại numpy:

cimport numpy as np 
import numpy as np 
cdef myfunction(np.ndarray[np.int64_t, ndim=1] y): 
    #do something 
    pass 

Bằng cách đó nó đọc rõ ràng hơn và sẽ không có bất kỳ sự nhầm lẫn sau này.

EDIT

Các memoryviews cú pháp mới sẽ là như thế này:

cdef myfunction(double[:] y): 
    #do something with y 
    pass 
+0

Cảm ơn thông tin chi tiết. Việc ném vào 'np.int64_t' có hoạt động trên mọi máy tính không? (Tôi biết rằng tôi đã hỏi liệu việc ném vào 'dtype = np.int32' có hoạt động trên tất cả các máy tính hay không, nhưng tùy chọn này nằm trong mã python. Tôi tự hỏi liệu tùy chọn' np.int64_t' bạn đã cung cấp ở trên có hoạt động trên tất cả các máy tính hay không , cho nó là mã cython.) – hlin117

+1

Tôi nghĩ vậy. Bởi vì nó nằm trong khai báo hàm, miễn là chúng ta chuyển mảng 'np.int64' vào nó, nó sẽ làm tốt. Cách thức nội bộ 'np.int64_t' sẽ được dịch thành 'C', gõ vào nó' numpy', không phải vấn đề của chúng ta (và tôi tin rằng nó đã được xử lý,: P). Xin lỗi đây không phải là câu trả lời dứt khoát, nhưng tôi đã thấy việc sử dụng này trong hướng dẫn và mã của người khác khá thường xuyên. –

+2

Tôi tin rằng cú pháp memoryview bây giờ được ưa thích để tuyên bố nó như là một mảng numpy (nó hoạt động nhiều hơn nói chung, và ở tốc độ cơ bản tương tự). Tuy nhiên, điểm về 'np.int64' là đúng. – DavidW

0

Tôi đã làm những gì được thông báo lỗi nói với tôi: Tôi đã thay đổi kiểu memoryview cơ sở từ int để long và nó dường như công việc.

%%cython 
def fun(long[:] x): 
    return x[0] 

y=np.array([1,2,3],dtype=int) 
fun(y) # returns 1 
0

Tôi gặp vấn đề tương tự. Được khích lệ bởi câu trả lời của Yibo, tôi đã sử dụng .astype (int), giải quyết vấn đề.

Các vấn đề liên quan