Cython: “致命错误:numpy/arrayobject.h: 没有此文件或目录”

189 投票
8 回答
129173 浏览
提问于 2025-04-17 14:30

我正在尝试用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()

8 个回答

21

这个错误的意思是在编译的时候找不到一个numpy的头文件。

你可以试着运行 export CFLAGS=-I/usr/lib/python2.7/site-packages/numpy/core/include/,然后再进行编译。这是几个不同软件包都会遇到的问题。在ArchLinux上也有一个关于这个问题的bug记录:https://bugs.archlinux.org/task/22326

53

对于像你这样的单文件项目,另一个选择是使用 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

268

在你的 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()]
)    

撰写回答