Cython:“致命错误:numpy/arrayobject.h:没有这样的文件或目录”
Posted
技术标签:
【中文标题】Cython:“致命错误:numpy/arrayobject.h:没有这样的文件或目录”【英文标题】:Cython: "fatal error: numpy/arrayobject.h: No such file or directory" 【发布时间】:2013-01-17 10:03:40 【问题描述】:我正在尝试使用 Cython 加快回答 here 的速度。我尝试编译代码(在完成cygwinccompiler.py
hack 解释here 之后),但得到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()
【问题讨论】:
您可以为您使用的操作系统添加标签吗? @tcaswell 64 位 Windows 7。 添加了 windows 标签,希望这将有助于知道如何使用 windows 的人(不像我)看到这个问题。 我找到了this。有些术语在我头上,但我要检查一下。 这能回答你的问题吗? Make distutils look for numpy header files in the correct place 【参考方案1】:该错误表示编译期间未找到 numpy 头文件。
尝试做export CFLAGS=-I/usr/lib/python2.7/site-packages/numpy/core/include/
,然后编译。这是几个不同软件包的问题。 ArchLinux 中针对同一问题提交了一个错误:https://bugs.archlinux.org/task/22326
【讨论】:
在哪里添加export
行?在我的setup.py
文件中?
不,这是一个 shell 命令。在你的 shell 中运行它,然后开始编译。
@NoobSaibot 在 shell 中(运行 python setup.py
)首先运行 export ..
命令。它设置 shell 的环境变量,与 [pc]ython 没有任何直接关系。
@tcaswell:我也这么认为。我正在使用 cmd,并得到了这个 'export' is not recognized as an internal or external command, operable program or batch file.
错误......只是无法用这个获胜......
@NoobSaibot 你得到了 lunix 的答案,因为你闻起来像 Windows 问题......【参考方案2】:
在您的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()]
)
【讨论】:
我为什么需要np.import_array()
?不是Numpy C-API吗?
我尝试了你的想法,但现在我收到了这个太长的疯狂错误,无法在此处发布,但它以 warning: untitled.pyx:8:49: Buffer unpacking not optimized away.
开头
啊,没错,你可能不需要np.import_array()
。不过,我很少在没有它的情况下编写使用 numpy 的 Cython 扩展,所以我习惯于使用它。至于您的其他问题,您引用的只是警告,而不是错误。如果您还有其他需要修复的错误,请发新帖。
include_dirs=[numpy.get_include()]
是个好技巧,谢谢!
include_dirs
传递给 setup()
在最新的 distutils 中被忽略,它必须传递给每个 Extension
,至少在 mac 上【参考方案3】:
对于像您这样的单文件项目,另一种选择是使用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
如何影响我的代码速度?最后,这里的部分:"Since Cython 0.11, the pyximport module also has experimental compilation support for normal Python modules..." 暗示它仍有一些问题需要解决。你能解释一下吗?
关于“对普通 Python 模块的实验性编译支持”——使用我上面建议的代码,.py
模块可以正常编译(不使用 cython),而 .pyx
模块使用 cython 编译。如果您将pyimport = True
传递给pyximport.install()
,那么它将使用cython 处理所有内容,甚至例如import random
或import os
。我不建议使用该功能,仅仅是因为没有令人信服的理由来使用它,而且它可能会产生问题。它可能主要由 cython 开发人员使用。
如果pyximport
工作正常,它将创建与任何其他方法完全相同的 C 代码。所以试试看。我指的是当编译过程足够复杂时,例如指向外部系统库的链接,您可能会发现 pyximport 失败,您需要 setup.py
和 cythonize
来准确指定如何构建它。但是你的.pyx
模块有import
s 或cimport
s 并不意味着它不能用pyximport
编译;可能完全没问题。
这很好用!但如果你已经安装了 msvc,我推荐 --compiler=msvc。那你就不需要安装mingw了。【参考方案4】:
简单回答
一种更简单的方法是将路径添加到您的文件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
【讨论】:
【参考方案5】:它应该可以在cythonize()
提到的here 函数中执行此操作,但它不起作用,因为有一个known issue
【讨论】:
【参考方案6】:如果你懒得写设置文件和找出包含目录的路径,
试试cyper。它可以编译你的 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
安装cyper。
【讨论】:
【参考方案7】:根据this answer,如果您在Linux上安装了numpy
和pip
,则需要手动设置/usr/include/numpy
的符号链接
就我而言,路径是:
sudo ln -s /usr/local/lib/python3.8/dist-packages/numpy/core/include/numpy/ /usr/include/numpy
【讨论】:
【参考方案8】:我在运行的服务器上没有 sudo 权限,并且导出 CFLAGS 对我不起作用。为了简单起见,我安装了 Anaconda ( https://docs.anaconda.com/anaconda/install/) 创建指向所有已安装包的链接,包括 Numpy。您还可以安装 miniconda 并使用环境以避免占用过多空间。
【讨论】:
你确定这回答了这个问题吗?请阅读How to Answer。以上是关于Cython:“致命错误:numpy/arrayobject.h:没有这样的文件或目录”的主要内容,如果未能解决你的问题,请参考以下文章