Próbuję tu przyspieszyć odpowiedź , używając Cythona. Próbuję skompilować kod (po wykonaniu cygwinccompiler.py
włamania opisanego tutaj ), ale pojawia się fatal error: numpy/arrayobject.h: No such file or directory...compilation terminated
błąd. Czy ktoś może mi powiedzieć, czy jest to problem z moim kodem, czy jakaś ezoteryczna subtelność w Cythonie?
Poniżej znajduje się mój kod.
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()
Odpowiedzi:
W twoim
setup.py
,Extension
powinni mieć argumentinclude_dirs=[numpy.get_include()]
.Brakuje również
np.import_array()
twojego kodu.-
Przykład setup.py:
from distutils.core import setup, Extension from Cython.Build import cythonize import numpy setup( ext_modules=[ Extension("my_module", ["my_module.c"], include_dirs=[numpy.get_include()]), ], ) # Or, if you use cythonize() to make the ext_modules list, # include_dirs can be passed to setup() setup( ext_modules=cythonize("my_module.pyx"), include_dirs=[numpy.get_include()] )
źródło
np.import_array()
? Czy to nie dotyczy Numpy C-API ?warning: untitled.pyx:8:49: Buffer unpacking not optimized away.
np.import_array()
. Rzadko jednak piszę numpy-using Cython bez niego, więc używam go z przyzwyczajenia. Jeśli chodzi o twój inny problem, to, co zacytowałeś, jest tylko ostrzeżeniem, a nie błędem. Jeśli masz inne błędy, które wymagają naprawy, napisz nowy wpis.include_dirs=[numpy.get_include()]
to fajna sztuczka, dziękuję!include_dirs
przekazany dosetup()
zostaje zignorowany w najnowszych dystrybucjach, musi zostać przekazany każdemuExtension
, przynajmniej na macW przypadku projektu jednoplikowego, takiego jak Twój, inną alternatywą jest użycie
pyximport
. Nie musisz tworzyćsetup.py
... nie musisz nawet otwierać wiersza poleceń, jeśli używasz IPython ... to wszystko jest bardzo wygodne. W twoim przypadku spróbuj uruchomić te polecenia w IPythonie lub w zwykłym skrypcie Python:import numpy import pyximport pyximport.install(setup_args={"script_args":["--compiler=mingw32"], "include_dirs":numpy.get_include()}, reload_support=True) import my_pyx_module print my_pyx_module.some_function(...) ...
Oczywiście może zajść potrzeba edycji kompilatora. Dzięki temu import i ponowne ładowanie działają tak samo dla
.pyx
plików, jak dla.py
plików.Źródło: http://wiki.cython.org/InstallingOnWindows
źródło
pyximport
wpływa na szybkość mojego kodu? I wreszcie sekcja tutaj: „ Od Cythona 0.11, moduł pyximport obsługuje również eksperymentalną kompilację dla zwykłych modułów Pythona …” sugeruje, że nadal ma kilka problemów do rozwiązania. Czy możesz to również wyjaśnić?.py
moduły są kompilowane normalnie (nie z cythonem), podczas gdy.pyx
moduły są kompilowane z cythonem. Jeśli przejdzieszpyimport = True
dopyximport.install()
, użyje cythonu do wszystkiego, nawet na przykładimport random
lubimport os
. Nie sugeruję korzystania z tej funkcji, po prostu dlatego, że nie ma ważnego powodu, aby z niej korzystać, a może to powodować problemy. Prawdopodobnie jest używany głównie przez programistów cython.pyximport
w ogóle zadziała, utworzy dokładnie ten sam kod C, co każda inna metoda. Więc spróbuj i zobacz. Byłem odnosząc się do faktu, że gdy proces kompilacji jest wystarczająco skomplikowane, np linki do zewnętrznych bibliotek systemowych, możesz stwierdzić, że pyximport zawiedzie i trzebasetup.py
icythonize
określić dokładnie, jak go zbudować. Ale fakt, że twój.pyx
moduł maimport
s lubcimport
s, nie oznacza, że nie można go skompilowaćpyximport
; może być całkiem dobrze.Ten błąd oznacza, że plik nagłówkowy numpy nie został znaleziony podczas kompilacji.
Spróbuj zrobić
export CFLAGS=-I/usr/lib/python2.7/site-packages/numpy/core/include/
, a następnie skompiluj. Jest to problem z kilkoma różnymi pakietami. W ArchLinux został zgłoszony błąd dotyczący tego samego problemu: https://bugs.archlinux.org/task/22326źródło
export
linię? W moimsetup.py
pliku?python setup.py
) uruchomexport ..
komendę jako pierwszą. Ustawia zmienne środowiskowe powłoki, a nie ma bezpośredniego związku z [pc] ython.'export' is not recognized as an internal or external command, operable program or batch file.
błąd ... po prostu nie mogę wygrać z tym ...Prosta odpowiedź
O wiele prostszym sposobem jest dodanie ścieżki do pliku
distutils.cfg
. Domyślnie jest to nazwa ścieżki systemu Windows 7C:\Python27\Lib\distutils\
. Po prostu potwierdzasz następującą zawartość i powinno się udać:Cały plik konfiguracyjny
Aby dać ci przykład, jak mógłby wyglądać plik konfiguracyjny, cały mój plik czyta:
źródło
Powinien być w stanie to zrobić w ramach
cythonize()
funkcji, jak wspomniano tutaj , ale nie działa, ponieważ występuje znany problemźródło
Jeśli jesteś zbyt leniwy, aby pisać pliki instalacyjne i znaleźć ścieżkę do katalogów nagłówków , wypróbuj cyper . Może skompilować Twój kod Cythona i
include_dirs
automatycznie ustawić Numpy.Załaduj swój kod do ciągu, a następnie po prostu uruchom
cymodule = cyper.inline(code_string)
, a Twoja funkcja będzie dostępnacymodule.sparsemaker
natychmiast. Coś takiegocode = open(your_pyx_file).read() cymodule = cyper.inline(code) cymodule.sparsemaker(...) # do what you want with your function
Możesz zainstalować cypera za pośrednictwem
pip install cyper
.źródło