Cython: "фатальна помилка: numpy / arrayobject.h: Немає такого файлу чи каталогу"


133

Я намагаюся прискорити відповідь тут, використовуючи Cython. Я намагаюся скомпілювати код (після того, як cygwinccompiler.pyхак пояснив тут ), але отримую fatal error: numpy/arrayobject.h: No such file or directory...compilation terminatedпомилку. Хтось може мені сказати, чи це проблема з моїм кодом, або якась езотерична тонкість із Cython?

Нижче мій код.

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()

чи можете ви додати тег до якої ОС ви використовуєте?
tacaswell

@tcaswell 64-розрядна Windows 7.
Noob Saibot

додав тег Windows, сподіваюся, що допоможе цю проблему побачити люди, які вміють користуватися Windows (на відміну від мене).
tacaswell

1
Я це знайшов . Деяка термінологія знаходиться над моєю головою, але я це перевірю.
Noob Saibot

Відповіді:


186

У вашому setup.pyвипадку Extensionмає бути аргумент include_dirs=[numpy.get_include()].

Також np.import_array()у вашому коді відсутній .

-

Приклад 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()]
)    

4
Навіщо мені це потрібно np.import_array()? Це не для Numpy C-API ?
Noob Saibot

Я спробував вашу ідею, але тепер я отримую цю шалену помилку, яку занадто довго розміщувати тут, але це починається зwarning: untitled.pyx:8:49: Buffer unpacking not optimized away.
Noob Saibot

Ах, правда, вам, мабуть, не потрібно np.import_array(). Я рідко пишу без наборів розширення Cython без нього, тому використовую це як звичку. Щодо іншої вашої проблеми, те, що ви цитували, - це лише попередження, а не помилка. Якщо у вас є інші помилки, які потребують виправлення, будь ласка, створіть нову публікацію.
Роберт Керн

1
include_dirs=[numpy.get_include()]приємний трюк дякую!
Даніель Фаррелл

14
include_dirsпередано, щоб setup()ігноруватися в останніх дистрибутивах, його потрібно передавати кожному Extension, принаймні на mac
дефісі

45

Для однофайлового проекту, як вашого, використовується інша альтернатива pyximport. Вам не потрібно створювати setup.py... вам навіть не потрібно відкривати командний рядок, якщо ви використовуєте IPython ... все це дуже зручно. У вашому випадку спробуйте виконати ці команди в IPython або в звичайному сценарії 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(...)
...

Можливо, вам знадобиться відредагувати компілятор. Це змушує імпортувати та перезавантажувати такі ж .pyxфайли, як і .pyфайли.

Джерело: http://wiki.cython.org/InstallingOnWindows


Дякую, @SteveB. Але чи можете ви детальніше розібратися в тому, що ви маєте на увазі під « Файловим проектом, як ваш ...»? Наведений вище модуль є однією (хоча і важливою) частиною більшого додатка. Як pyximportвпливає швидкість мого коду? І нарешті, розділ тут: " Оскільки Cython 0,11, модуль pyximport також має експериментальну підтримку компіляції для звичайних модулів Python ..." , це означає, що він ще має деякі переробки. Чи можете ви це також пояснити?
Noob Saibot

1
Знову "підтримка експериментальної компіляції для звичайних модулів Python" - з кодом, який я запропонував вище, .pyмодулі компілюються нормально (а не з cython), тоді як .pyxмодулі збираються з cython. Якщо ви перейдете pyimport = Trueв нього pyximport.install(), то він буде використовувати цитон для всього, навіть наприклад, import randomабо import os. Я не пропоную використовувати цю функцію просто тому, що немає вагомих причин її використовувати, і це може створити проблеми. Ймовірно, використовується в основному розробниками цитону.
Стів Бернс

Якщо pyximportвін взагалі працює, він створить такий самий код C, як і будь-який інший метод. Тож спробуйте і подивіться. Я мав у виду той факт , що , коли процес компіляції досить складно, наприклад , посилання на зовнішні бібліотеки системи, ви можете виявити , що pyximport зазнає невдачі , і вам потрібно , setup.pyі cythonizeточно вказати , як побудувати його. Але той факт, що ваш .pyxмодуль має imports або cimports, не означає, що його неможливо скласти pyximport; це може бути абсолютно нормально.
Стів Бернс

У мене є посада Cython, про яку ви, можливо, зможете ознайомитись.
Філліп

14

Помилка означає, що під час компіляції не знайдено файлу заголовка numpy.

Спробуйте зробити export CFLAGS=-I/usr/lib/python2.7/site-packages/numpy/core/include/, а потім скласти. Це проблема з декількома різними пакетами. У ArchLinux подано помилку за тією ж проблемою: https://bugs.archlinux.org/task/22326


Де додати exportрядок? У моєму setup.pyфайлі?
Noob Saibot

Ні, це команда оболонки. Запустіть його в своїй оболонці, а потім почніть компілювати.
Джон Броді

@NoobSaibot в оболонці (де ви запускаєте python setup.py) export ..спочатку запустіть команду. Він встановлює змінні середовища оболонки, не пов'язані безпосередньо з [pc] ython.
tacaswell

@tcaswell: Я зрозумів стільки ж. Я використовую cmd, і я отримав цю 'export' is not recognized as an internal or external command, operable program or batch file.помилку ... просто не можу перемогти з цією ...
Noob Saibot

4
@NoobSaibot ви отримуєте відповіді на лунікс за те, що пахне проблемою Windows ....
tacaswell

1

Проста відповідь

Більш простий спосіб - додати шлях до вашого файлу distutils.cfg. Це ім'я Windows 7 за замовчуванням C:\Python27\Lib\distutils\. Ви просто стверджуєте наступний вміст, і він повинен вийти:

[build_ext]
include_dirs= C:\Python27\Lib\site-packages\numpy\core\include

Весь конфігураційний файл

Щоб навести приклад того, як може виглядати файл конфігурації, весь мій файл читає:

[build]
compiler = mingw32

[build_ext]
include_dirs= C:\Python27\Lib\site-packages\numpy\core\include
compiler = mingw32


1

Якщо ви лінуєтеся писати налаштування файлів і намітити шлях для включення каталогів, спробуйте cyper . Він може скласти ваш код Cython і встановити include_dirsдля Numpy автоматично.

Завантажте свій код у рядок, а потім просто запустіть cymodule = cyper.inline(code_string), тоді ваша функція доступна як cymodule.sparsemakerмиттєво. Щось на зразок цього

code = open(your_pyx_file).read()
cymodule = cyper.inline(code)

cymodule.sparsemaker(...)
# do what you want with your function

Ви можете встановити cyper через pip install cyper.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.