Ich versuche hier die Antwort mit Cython zu beschleunigen . Ich versuche, den Code zu kompilieren (nachdem ich den hiercygwinccompiler.py
erläuterten Hack ausgeführt habe ), erhalte jedoch eine Fehlermeldung. Kann mir jemand sagen, ob es ein Problem mit meinem Code oder eine esoterische Subtilität mit Cython ist?fatal error: numpy/arrayobject.h: No such file or directory...compilation terminated
Unten ist mein Code.
import numpy as np
import scipy as sp
cimport numpy as np
cimport cython
cdef inline np.ndarray[np.int, ndim=1] fbincount(np.ndarray[np.int_t, ndim=1] x):
cdef int m = np.amax(x)+1
cdef int n = x.size
cdef unsigned int i
cdef np.ndarray[np.int_t, ndim=1] c = np.zeros(m, dtype=np.int)
for i in xrange(n):
c[<unsigned int>x[i]] += 1
return c
cdef packed struct Point:
np.float64_t f0, f1
@cython.boundscheck(False)
def sparsemaker(np.ndarray[np.float_t, ndim=2] X not None,
np.ndarray[np.float_t, ndim=2] Y not None,
np.ndarray[np.float_t, ndim=2] Z not None):
cdef np.ndarray[np.float64_t, ndim=1] counts, factor
cdef np.ndarray[np.int_t, ndim=1] row, col, repeats
cdef np.ndarray[Point] indices
cdef int x_, y_
_, row = np.unique(X, return_inverse=True); x_ = _.size
_, col = np.unique(Y, return_inverse=True); y_ = _.size
indices = np.rec.fromarrays([row,col])
_, repeats = np.unique(indices, return_inverse=True)
counts = 1. / fbincount(repeats)
Z.flat *= counts.take(repeats)
return sp.sparse.csr_matrix((Z.flat,(row,col)), shape=(x_, y_)).toarray()
Antworten:
In Ihrem
setup.py
, dasExtension
sollte das Argument hatinclude_dirs=[numpy.get_include()]
.Außerdem fehlen Sie
np.import_array()
in Ihrem Code.- -
Beispiel setup.py:
quelle
np.import_array()
? Ist das nicht für die Numpy C-API ?warning: untitled.pyx:8:49: Buffer unpacking not optimized away.
np.import_array()
. Ich schreibe jedoch selten numpy-verwendende Cython-Erweiterungen ohne diese, daher verwende ich sie aus Gewohnheit. Was Ihr anderes Problem betrifft, ist das, was Sie zitiert haben, nur eine Warnung, kein Fehler. Wenn Sie andere Fehler haben, die behoben werden müssen, erstellen Sie bitte einen neuen Beitrag.include_dirs=[numpy.get_include()]
ist ein schöner Trick danke!include_dirs
übergeben ansetup()
wird in den neuesten distutils ignoriert, es muss an jeden weitergegeben werdenExtension
, zumindest auf macFür ein Projekt mit einer Datei wie Ihres können Sie auch eine andere Alternative verwenden
pyximport
. Sie müssen keine erstellensetup.py
... Sie müssen nicht einmal eine Befehlszeile öffnen, wenn Sie IPython verwenden ... alles ist sehr praktisch. Versuchen Sie in Ihrem Fall, diese Befehle in IPython oder in einem normalen Python-Skript auszuführen:Möglicherweise müssen Sie den Compiler natürlich bearbeiten. Dadurch funktionieren Import und Neuladen für
.pyx
Dateien genauso wie für.py
Dateien.Quelle: http://wiki.cython.org/InstallingOnWindows
quelle
pyximport
auf die Geschwindigkeit meines Codes aus? Und schließlich impliziert der Abschnitt hier: " Seit Cython 0.11 bietet das Pyximport-Modul auch experimentelle Kompilierungsunterstützung für normale Python-Module ..." impliziert, dass noch einige Probleme zu lösen sind. Kannst du das auch erklären?.py
Module normal kompiliert (nicht mit Cython), während.pyx
Module mit Cython kompiliert werden. Wenn Siepyimport = True
in übergebenpyximport.install()
, wird Cython für alles verwendet, auch zum Beispielimport random
oderimport os
. Ich schlage nicht vor, diese Funktion zu verwenden, nur weil es keinen zwingenden Grund gibt, sie zu verwenden, und sie könnte Probleme verursachen. Es wird wahrscheinlich hauptsächlich von Cython-Entwicklern verwendet.pyximport
funktioniert, wird genau der gleiche C-Code wie bei jeder anderen Methode erstellt. Also probieren Sie es aus und sehen Sie. Ich bezog mich auf die Tatsache, dass wenn der Kompilierungsprozess ausreichend kompliziert ist, z. B. Links zu externen Systembibliotheken, Sie möglicherweise feststellen, dass pyximport fehlschlägt und Sie einsetup.py
und benötigencythonize
, um genau anzugeben, wie es erstellt werden soll. Die Tatsache, dass Ihr.pyx
Modulimport
s odercimport
s hat, bedeutet jedoch nicht, dass es nicht kompiliert werden kannpyximport
. es kann durchaus in Ordnung sein.Der Fehler bedeutet, dass beim Kompilieren keine Numpy-Header-Datei gefunden wird.
Versuchen Sie es
export CFLAGS=-I/usr/lib/python2.7/site-packages/numpy/core/include/
und kompilieren Sie dann. Dies ist ein Problem mit einigen verschiedenen Paketen. In ArchLinux wurde ein Fehler für dasselbe Problem gemeldet : https://bugs.archlinux.org/task/22326quelle
export
Zeile hinzu? In meinersetup.py
Akte?python setup.py
) führen Sie zuerst denexport ..
Befehl aus. Es legt die Umgebungsvariablen der Shell fest und hat nichts direkt mit [pc] ython zu tun.'export' is not recognized as an internal or external command, operable program or batch file.
Fehler ... kann mit diesem einfach nicht gewinnen ...Einfache Antwort
Eine einfachere Möglichkeit besteht darin, den Pfad zu Ihrer Datei hinzuzufügen
distutils.cfg
. Der Pfad für Windows 7 ist standardmäßigC:\Python27\Lib\distutils\
. Sie behaupten nur die folgenden Inhalte und es sollte funktionieren:Ganze Konfigurationsdatei
Um Ihnen ein Beispiel zu geben, wie die Konfigurationsdatei aussehen könnte, lautet meine gesamte Datei:
quelle
Es sollte in der Lage sein, dies innerhalb der hier
cythonize()
erwähnten Funktion zu tun , aber es funktioniert nicht, da ein bekanntes Problem vorliegtquelle
Wenn Sie zu faul sind, um Setup-Dateien zu schreiben und den Pfad für Include-Verzeichnisse herauszufinden, versuchen Sie es mit cyper . Es kann Ihren Cython-Code kompilieren und
include_dirs
automatisch auf Numpy einstellen.Laden Sie Ihren Code in eine Zeichenfolge, führen Sie ihn einfach aus
cymodule = cyper.inline(code_string)
, und Ihre Funktion istcymodule.sparsemaker
sofort verfügbar . Etwas wie dasSie können cyper über installieren
pip install cyper
.quelle