我正在尝试使用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()
答案 0 :(得分:148)
在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()]
)
答案 1 :(得分:37)
对于像您这样的单文件项目,另一种方法是使用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
文件的工作相同。
答案 2 :(得分:11)
错误表示在编译期间未找到numpy头文件。
尝试执行export CFLAGS=-I/usr/lib/python2.7/site-packages/numpy/core/include/
,然后进行编译。这是几个不同包的问题。 ArchLinux中存在针对同一问题提交的错误:https://bugs.archlinux.org/task/22326
答案 3 :(得分: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
答案 4 :(得分:1)
如果您懒得写设置文件并弄清楚包含目录的路径,
尝试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。
答案 5 :(得分:0)
它应该能够在here所述的String.prototype.formatUnicorn = String.prototype.formatUnicorn || function () {
var e = this.toString();
if (!arguments.length)
return e;
var t = typeof arguments[0],
n = "string" == t || "number" == t ? Array.prototype.slice.call(arguments) : arguments[0];
for (var i in n)
e = e.replace(new RegExp("\\{" + i + "\\}", "gi"), n[i]);
return e
}
/** Lets Assume your Code
genGetLocations:{
data_url:'restaurants/{var1}/tables/{var2},
}**/
console.log('restaurants/{var1}/tables/{var2}'.formatUnicorn({'var1':'test1','var2':'test2'}))
函数中执行此操作,但是由于存在一个known issue
答案 6 :(得分:0)
根据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