J'essaye d'accélérer la réponse ici en utilisant Cython. J'essaye de compiler le code (après avoir fait le cygwinccompiler.py
hack expliqué ici ), mais j'obtiens une fatal error: numpy/arrayobject.h: No such file or directory...compilation terminated
erreur. Quelqu'un peut-il me dire si c'est un problème avec mon code, ou une subtilité ésotérique avec Cython?
Ci-dessous mon 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()
Réponses:
Dans votre
setup.py
, leExtension
devrait avoir l'argumentinclude_dirs=[numpy.get_include()]
.De plus, vous manquez
np.import_array()
dans votre code.-
Exemple setup.py:
la source
np.import_array()
? N'est-ce pas pour l' API C Numpy ?warning: untitled.pyx:8:49: Buffer unpacking not optimized away.
np.import_array()
. J'écris rarement des extensions Cython avec numpy sans cela, donc je l'utilise par habitude. Quant à votre autre problème, ce que vous avez cité n'est qu'un avertissement, pas une erreur. Si vous avez d'autres erreurs à corriger, veuillez publier un nouveau message.include_dirs=[numpy.get_include()]
c'est un joli truc merci!include_dirs
passé àsetup()
est ignoré dans les derniers distutils, il doit être transmis à chacunExtension
, au moins sur macPour un projet à un fichier comme le vôtre, une autre alternative consiste à utiliser
pyximport
. Vous n'avez pas besoin de créer unsetup.py
... vous n'avez même pas besoin d'ouvrir une ligne de commande si vous utilisez IPython ... c'est très pratique. Dans votre cas, essayez d'exécuter ces commandes en IPython ou dans un script Python normal:Vous devrez peut-être modifier le compilateur bien sûr. Cela fait que l'importation et le rechargement fonctionnent de la même manière pour les
.pyx
fichiers que pour.py
fichiers.Source: http://wiki.cython.org/InstallingOnWindows
la source
pyximport
affecte la vitesse de mon code? Et enfin, la section ici: " Depuis Cython 0.11, le module pyximport a également un support de compilation expérimentale pour les modules Python normaux ..." implique qu'il a encore quelques problèmes à résoudre. Pouvez-vous expliquer cela également?.py
modules sont compilés normalement (pas avec cython) tandis que les.pyx
modules sont compilés avec cython. Si vous passezpyimport = True
danspyximport.install()
, alors il utilisera cython pour tout, même par exempleimport random
ouimport os
. Je ne suggère pas d'utiliser cette fonctionnalité, simplement parce qu'il n'y a aucune raison impérieuse de l'utiliser, et cela pourrait créer des problèmes. Il est probablement principalement utilisé par les développeurs cython.pyximport
fonctionne, cela créera exactement le même code C que toute autre méthode. Alors essayez-le et voyez. Je faisais référence au fait que lorsque le processus de compilation est suffisamment compliqué, par exemple des liens vers des bibliothèques système externes, vous pourriez constater que pyximport échoue et que vous avez besoin d'unsetup.py
etcythonize
pour spécifier exactement comment le construire. Mais le fait que votre.pyx
module aitimport
s oucimport
s ne signifie pas qu'il ne peut pas être compilé avecpyximport
; ça peut bien être tout à fait bien.L'erreur signifie qu'un fichier d'en-tête numpy n'est pas trouvé lors de la compilation.
Essayez de faire
export CFLAGS=-I/usr/lib/python2.7/site-packages/numpy/core/include/
, puis compilez. C'est un problème avec quelques packages différents. Il y a un bogue déposé dans ArchLinux pour le même problème: https://bugs.archlinux.org/task/22326la source
export
ligne? Dans monsetup.py
dossier?python setup.py
) exécutez d'abord laexport ..
commande. Il définit les variables d'environnement du shell, rien à voir directement avec [pc] ython.'export' is not recognized as an internal or external command, operable program or batch file.
erreur ... je ne peux tout simplement pas gagner avec celui-ci ...Réponse simple
Un moyen plus simple consiste à ajouter le chemin d'accès à votre fichier
distutils.cfg
. Son nom de chemin de Windows 7 est par défautC:\Python27\Lib\distutils\
. Vous venez d'affirmer le contenu suivant et cela devrait fonctionner:Fichier de configuration complet
Pour vous donner un exemple à quoi le fichier de configuration pourrait ressembler, mon fichier entier se lit comme suit:
la source
Il devrait être capable de le faire dans la
cythonize()
fonction mentionnée ici , mais cela ne fonctionne pas car il y a un problème connula source
Si vous êtes trop paresseux pour écrire des fichiers de configuration et déterminer le chemin des répertoires d'inclusion, essayez cyper . Il peut compiler votre code Cython et définir
include_dirs
automatiquement Numpy.Chargez votre code dans une chaîne, puis exécutez simplement
cymodule = cyper.inline(code_string)
, puis votre fonction est disponiblecymodule.sparsemaker
instantanément. Quelque chose comme çaVous pouvez installer cyper via
pip install cyper
.la source