%%cython_pyximport ImportError:构建模块函数失败:['DistutilsPlatf



在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。我想我应该绕过所有可能的错误

  1. 首先,你需要编译cython使用:

    cython_commands = ['cython', '-a', '-l', '-p', '-o', c_file_name, file_path]
    cython_feedback = subprocess.call(cython_commands)
    
  2. 然后你需要把这个。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

相关内容

  • 没有找到相关文章

最新更新