2015-08-28 4 views
7

У меня возникли проблемы с передачей в этой памяти целых чисел в эту (довольно тривиальную) функцию. Python дает мне эту ошибку:Cython: несоответствие типа буфера, ожидаемое 'int', но получившее 'long'

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

Может кто-нибудь помочь мне понять, что происходит? Поиск в stackoverflow, кажется, имеет отношение к тому, как python интерпретирует типы и как C интерпретирует типы.

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

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

Это производит ValueError сверху.

EDIT: Вот некоторые другие вещи, которые я обнаружил.

Для уточнения, эта ошибка будет повторяться, если я объявляю y следующими способами:

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) 

Однако, это работает, если я объявляю y с

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

ли кто-то хочет дать предложение, почему это это так? Будет ли метать в np.int32 работы на разных компьютерах? (Я использую macbook pro retina, 2013.)

ответ

9

Вы используете Cyteon's int, который является только Cint. Я думаю, что на Mac (или на большинстве архитектур) он 32-битный. См wiki или intel или Does the size of an int depend on the compiler and/or processor?

С другой стороны, long означает int64. dtype='int' или dtype=np.int эквивалентны np.int64.

Я думаю, вы могли бы просто явно определить его в качестве одного из numpy типа:

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

Таким образом, он читает более ясно, и не будет никакой путаницы позже.

EDIT

Поздние memoryviews синтаксис будет выглядеть так:

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

Спасибо за понимание. Будет ли метать в 'np.int64_t' работу на каждом компьютере? (Я знаю, что я спросил, будет ли метать в dtype = np.int32' на всех компьютерах, но этот параметр был в коде python. Мне интересно, работает ли опция np.int64_t', приведенная выше, на всех компьютерах , учитывая, что это код cython.) – hlin117

+1

Думаю, что да. Поскольку он находится в объявлении функции, пока мы передаем массив 'np.int64', он будет работать нормально. Как внутренне 'np.int64_t' будет переведен в 'C', это проблема' numpy', а не наша проблема (и я бы поверила, что об этом уже позаботились: P). Извините, это не окончательный ответ, но я часто видел это использование в учебниках и кодексах других народов. –

+2

Я считаю, что синтаксис memoryview теперь предпочитает объявлять его как массив numpy (он работает в более общем плане и на той же скорости). Тем не менее, вопрос о 'np.int64' прав. – DavidW

0

Я сделал то, что сообщение об ошибке сказал мне: Я изменил memoryview базовый тип из int в long и, казалось, Работа.

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

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

У меня была та же проблема. Мотивированный ответом Ибо, я использовал .astype (int), который разрешил проблему.

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