Estou tentando acelerar a resposta aqui usando Cython. Eu tento compilar o código (depois de fazer o cygwinccompiler.py
hack explicado aqui ), mas recebo um fatal error: numpy/arrayobject.h: No such file or directory...compilation terminated
erro. Alguém pode me dizer se é um problema com o meu código ou alguma sutileza esotérica com o Cython?
Abaixo está o meu código.
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()
Respostas:
No seu
setup.py
, oExtension
deve ter o argumentoinclude_dirs=[numpy.get_include()]
.Além disso, você está ausente
np.import_array()
no seu código.-
Exemplo setup.py:
fonte
np.import_array()
? Não é isso para o Numpy C-API ?warning: untitled.pyx:8:49: Buffer unpacking not optimized away.
np.import_array()
. Porém, eu raramente escrevo extensões Cython que usam sonolentas sem ela, então eu as uso como uma questão de hábito. Quanto ao seu outro problema, o que você citou é apenas um aviso, não um erro. Se você tiver outros erros que precisam ser corrigidos, faça uma nova postagem.include_dirs=[numpy.get_include()]
é um bom truque, obrigado!include_dirs
passado parasetup()
fica ignorado nas últimas distutils, tem que ser passado para cadaExtension
, pelo menos no macPara um projeto de um arquivo como o seu, outra alternativa é usar
pyximport
. Você não precisa criar umsetup.py
... nem precisa abrir uma linha de comando se usar o IPython ... é tudo muito conveniente. No seu caso, tente executar estes comandos no IPython ou em um script Python normal:Pode ser necessário editar o compilador, é claro. Isso faz com que a importação e a recarga funcionem da mesma forma para os
.pyx
arquivos, assim como para os.py
arquivos.Fonte: http://wiki.cython.org/InstallingOnWindows
fonte
pyximport
afeta a velocidade do meu código? E finalmente, a seção aqui: " Desde o Cython 0.11, o módulo pyximport também oferece suporte à compilação experimental para módulos Python normais ..." implica que ele ainda tem algumas falhas para resolver. Você pode explicar isso também?.py
módulos são compilados normalmente (não com o cython) enquanto os.pyx
módulos são compilados com o cython. Se vocêpyimport = True
entrarpyximport.install()
, ele usará o cython para tudo, mesmo por exemploimport random
ouimport os
. Eu não sugiro usar esse recurso, simplesmente porque não há motivo convincente para usá-lo e isso pode criar problemas. Provavelmente é usado principalmente por desenvolvedores de cython.pyximport
funcionar, ele criará exatamente o mesmo código C de qualquer outro método. Então tente e veja. Eu estava me referindo ao fato de que quando o processo de compilação é suficientemente complicado, por exemplo, links para bibliotecas de sistema externas, você pode achar que o pyximport falha e você precisa de umsetup.py
ecythonize
para especificar exatamente como construí-lo. Mas o fato de seu.pyx
módulo terimport
s oucimport
s não significa que ele não possa ser compiladopyximport
; pode muito bem estar totalmente bem.O erro significa que um arquivo de cabeçalho numpy não está sendo encontrado durante a compilação.
Tente fazer
export CFLAGS=-I/usr/lib/python2.7/site-packages/numpy/core/include/
e, em seguida, compilar. Este é um problema com alguns pacotes diferentes. Há um erro registrado no ArchLinux para o mesmo problema: https://bugs.archlinux.org/task/22326fonte
export
linha? No meusetup.py
arquivo?python setup.py
), execute oexport ..
comando primeiro. Ele define as variáveis ambientais do shell, e nada diretamente relacionado ao [pc] ython.'export' is not recognized as an internal or external command, operable program or batch file.
erro ... simplesmente não posso ganhar com este ...Resposta simples
Uma maneira mais simples é adicionar o caminho ao seu arquivo
distutils.cfg
. O nome do caminho do Windows 7 é por padrãoC:\Python27\Lib\distutils\
. Você apenas afirma o seguinte conteúdo e deve funcionar:Arquivo de configuração inteiro
Para dar um exemplo de como o arquivo de configuração pode ser, meu arquivo inteiro diz:
fonte
Deve ser capaz de fazê-lo dentro da
cythonize()
função, conforme mencionado aqui , mas não funciona porque há um problema conhecidofonte
Se você estiver com preguiça de gravar arquivos de instalação e descobrir o caminho para os diretórios de inclusão, tente cyper . Ele pode compilar seu código Cython e configurar o
include_dirs
Numpy automaticamente.Carregue seu código em uma string, execute simplesmente
cymodule = cyper.inline(code_string)
e sua função estará disponívelcymodule.sparsemaker
instantaneamente. Algo assimVocê pode instalar o cyper via
pip install cyper
.fonte