Cython:”致命错误: numpy/arrayobject.h: 没有这样的文件或目录

我试图使用 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()
114382 次浏览

这个错误意味着在编译过程中没有找到 numpy 头文件。

尝试执行 export CFLAGS=-I/usr/lib/python2.7/site-packages/numpy/core/include/,然后编译。这是几个不同软件包的问题。在 ArchLinux 中也有一个相同问题的 bug: https://bugs.archlinux.org/task/22326

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

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

答案很简单

一种更简单的方法是将路径添加到文件 distutils.cfg。它的路径代表 Windows7默认是 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

它应该能够在 cythonize()的功能范围内完成,就像前面提到的 给你,但是它不能工作,因为有一个 已知问题

如果您懒得编写安装文件和指定 include 目录的路径, 尝试 柏草。它可以编译您的 Cython 代码,并设置自动为 Numpy 的 include_dirs

将代码加载到一个字符串中,然后简单地运行 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

你可以通过 pip install cyper安装柏草。

根据 这个答案,如果您已经在 Linux 上用 pip安装了 numpy,那么您将需要手动设置到 /usr/include/numpy的符号链接

在我的例子中,路径是:

sudo ln -s /usr/local/lib/python3.8/dist-packages/numpy/core/include/numpy/ /usr/include/numpy

我在运行的服务器上没有 sudo 特权,导出 CFLAGS 也不能用。为了简单起见,我安装了 Anaconda ( Https://docs.anaconda.com/anaconda/install/ ) ,它会创建指向所有已安装软件包(包括 Numpy)的链接。您还可以安装 miniconda 并与环境一起工作,以避免使用太多的空间。