在iPython Notebook中,我试图使用笔记本函数%%cython_pyximport
来编写一个cython函数,我可以稍后在笔记本中调用。
我想使用这个命令,而不是%%cython
,因为它似乎有相当多的开销。例如,当我分析我的代码时,我得到这个:
168495 function calls in 4.606 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
1 3.234 3.234 4.605 4.605 {_cython_magic_0ef63e1ad591c89b73223c7a86d78802.knn_alg}
11397 0.326 0.000 0.326 0.000 {method 'reduce' of 'numpy.ufunc' objects}
987 0.152 0.000 0.266 0.000 decomp.py:92(eig)
987 0.118 0.000 0.138 0.000 function_base.py:3112(delete)
我希望使用%%cython_pyximport
将减少调用这个函数所花费的时间。如果有更好的方法,请告诉我。
所以得到我的实际问题-当我使用%%cython_pyximport
我得到这个错误:
ImportError: Building module function failed: ['DistutilsPlatformError: Unable to find vcvarsall.batn']
也许这与我的路径上没有什么东西有关,但我不确定。我要怎么做才能解决这个问题?
我正在使用Windows 7, Python 2.7.6(安装与Anaconda), Cython 0.20.1, iPython Notebook 2.1.0
编辑:所以在遵循@IanH的建议后,我现在有这个错误:
fatal error: numpy/arrayobject.h: No such file or directory
似乎需要包含额外的头文件才能使numpy与pyximport一起工作。在本页https://github.com/cython/cython/wiki/InstallingOnWindows
中提到了此错误以及如何解决它,但我迷失了如何应用此错误,以便%%cython_pyximport命令将在我的笔记本中工作。
这里有两个不同的问题。我将先解决你似乎关心的问题。
使用pyximport而不是cython魔法函数根本不会提高速度。根据您的分析结果,这里的真正问题似乎是在循环内部调用NumPy函数。在Cython中,你必须跟踪哪些函数调用是用C完成的,哪些是用Python完成的。Numpy通用函数是Python函数,它们需要调用Python函数的代价。
你想如何解决这个问题完全取决于你在做什么。如果您可以使用NumPy操作巧妙地向量化循环,这可能是最好的方法,但并非所有问题都可以通过这种方式轻松解决。有很多方法可以从Cython调用LAPACK例程,如本文所述。如果你正在做更简单的操作(如沿轴求和等),你可以编写一个函数,使用cython memoryviews在cython模块内部传递切片。在这篇博文中有一些关于正确方法的讨论。在Cython中做这些操作通常有点困难,但它仍然是一个非常容易解决的问题。
现在,虽然我不相信pyximport实际上会做你想要的,我仍然会告诉你如何让它工作。您看到的错误发生在distutils试图使用Visual Studio编译器时,即使您还没有为它设置好一切。默认情况下,Anaconda为Cython扩展使用MinGW,但由于某些原因,它没有设置为在pyximport中使用MinGW。不过这很容易解决。在您的Python安装目录(可能是C:Anaconda
或类似的目录)中,应该有一个文件AnacondaLibdistutilsdistutils.cfg
。(如果它不存在,就创建它。)修改它,使其内容包含以下两个选项:
[build]
compiler=mingw32
[build_ext]
compiler = mingw32
如果我没记错的话,第一个已经包含在Anaconda中了。在撰写本文时,第二个还没有。您将需要它在那里使pyximport工作。
我遇到了同样的问题,所以我的解决方案是使用:
(建立)编译器= mingw32
。[build_ext]编译器= mingw32
在IanH的回答中,我只是选择直接调用gcc和cython。我想我应该绕过所有可能的错误
首先,你需要编译cython使用:
cython_commands = ['cython', '-a', '-l', '-p', '-o', c_file_name, file_path] cython_feedback = subprocess.call(cython_commands)
然后你需要把这个。c文件通过告诉编译器在哪里寻找python库来编译它。
gcc_commands = ['gcc', '-shared', '-Wall', '-O3', '-I', py_include_dir, '-L', py_libs_dir, '-o', output_name, c_file_name, '-l', a_lib] gcc_error = subprocess.call(gcc_commands)
py_include_dir: python安装中标记为'include'的目录的路径
py_libs_dir: python安装中标记为'libs'的目录的路径
c_file_name:中间人c文件的路径
a_lib: python安装的名称。'python34'或'python35'或'python27')
由于我已经安装了VS2015,必须添加新的环境变量
SET VS90COMNTOOLS=%VS140COMNTOOLS%
源https://stackoverflow.com/a/10558328/625189