2015-08-28 6 views
7

Ich habe Probleme, in diesem memoryview von ganzen Zahlen in diese (eher triviale) Funktion zu gehen. Python gibt mir diesen Fehler:Cython: Fehlertyp des Puffertyps, erwartet 'int', aber 'lang'

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

Kann mir jemand helfen zu verstehen, was vor sich geht? Bei der Suche nach stackoverflow scheint es damit zu tun zu haben, wie python Typen interpretiert und wie C Typen interpretiert.

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

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

Dies erzeugt die ValueError von oben.

EDIT: Hier sind einige andere Dinge, die ich entdeckt habe.

Um zu klären, bleibt dieser Fehler, wenn ich y folgende Möglichkeiten erklären:

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) 

Allerdings funktioniert es, wenn ich y mit

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

Hat jemand einen Vorschlag, warum diese geben wollen ist der Fall? Würden np.int32 auf verschiedenen Computern arbeiten? (Ich benutze ein macbook pro Retina, 2013.)

Antwort

9

Du Cython der int Art verwenden, die nur Cint ist. Ich denke auf Mac (oder den meisten Architekturen) ist es Int 32-Bit. Siehe wiki oder intel oder Does the size of an int depend on the compiler and/or processor?

Auf der anderen Seite, long bedeutet int64. dtype='int' oder dtype=np.int sind alle äquivalent zu np.int64.

Ich denke, man könnte nur explizit als eine der numpy Art definieren:

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

So liest es mehr klar und es wird keine Verwirrung später sein.

EDIT

Die neuere memoryviews Syntax so sein würde:

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

Danke für die Einsicht. Würde "np.int64_t" auf jedem Computer funktionieren? (Ich weiß, dass ich gefragt habe, ob das Eingeben von 'dtype = np.int32' auf allen Computern funktionieren würde, aber diese Option war im Python-Code. Ich frage mich, ob die oben beschriebene Option' np.int64_t' auf allen Computern funktioniert , da es Cython-Code ist.) – hlin117

+1

Ich denke schon. Weil es in der Funktionsdeklaration ist, solange wir ein 'np.int64'-Array an es übergeben, wird es gut gehen. Wie intern 'np.int64_t' würde in 'C' übersetzt werden, geben Sie das' numpy' Problem an, nicht unser Problem (und ich würde darauf vertrauen, dass es schon erledigt ist,: P). Entschuldigung, das ist keine definitive Antwort, aber ich habe diese Verwendung oft in Tutorials und Code anderer Leute gesehen. –

+2

Ich glaube, die Memoryview-Syntax wird jetzt bevorzugt, um es als ein numpy Array zu deklarieren (es funktioniert allgemeiner und im Grunde die gleiche Geschwindigkeit). Der Punkt über die 'np.int64' ist jedoch richtig. – DavidW

0

Ich tat, was die Fehlermeldung mir gesagt: ich von int zu long den memoryview Basistyp geändert und es schien Arbeit.

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

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

Ich hatte das gleiche Problem. Motiviert durch Yibos Antwort verwendete ich .astype (int), was das Problem löste.