快速教程:使用Cython来扩展Python/NumPy库

来源:互联网 发布:淘宝注册公司靠谱吗 编辑:程序博客网 时间:2024/06/08 17:19
北京 | 深度学习与人工智能研修
12月23-24日
再设经典课程 重温深度学习
阅读全文
>


正文共2583个字,7张图,预计阅读时间:7分钟。


前言


整个快速教程直接上例子,具体对Cython的使用可以看参考文章。以下工作均在Windows 10 + Python 2.7 + NumPy 1.11.0 + Cython 0.24 版本上进行。


正文


准备工作

 

假设现在我们用C实现了一个可以用在数组上的cos函数,函数原型如下:

 

// 对in_array中的前size个数求cos值,并存放在out_array对应位置上

void cos_doubles(double * in_array, double * out_array, int size);

 

那么总共需要4个文件:

 

cos_doubles.c,C源文件。


cos_doubles.h,C头文件。


_cos_doubles.pyx,Python的C扩展文件。(注意:之所以前面加个"_"下划线,是因为使用Cython编译打包后会对pyx文件生成同名的c文件,为了避免覆盖掉原来的cos_doubles.c文件,此处加个下划线)

setup.py,负责管理编译、打包工作的“配置”脚本。


下面给出4个文件的源代码:


cos_doubles.c


#include "cos_doubles.h"

#include <math.h>

 

/*  Compute the cosine of each element in in_array, storing the result in

 *  out_array. */

void cos_doubles(double * in_array, double * out_array, int size){

    int i;

    for(i=0;i<size;i++){

        out_array[i] = cos(in_array[i]);

    }

}


cos_doubles.h

#ifndef _COS_DOUBLES_H

#define _COS_DOUBLES_H

void cos_doubles(double * in_array, double * out_array, int size);

#endif


cos_doubles.pyx


""" Example of wrapping a C function that takes C double arrays as input using

    the Numpy declarations from Cython """

 

# import both numpy and the Cython declarations for numpy

import numpy as np

cimport numpy as np

 

# if you want to use the Numpy-C-API from Cython

# (not strictly necessary for this example)

np.import_array()

 

# cdefine the signature of our c function

cdef extern from "cos_doubles.h":

    void cos_doubles (double * in_array, double * out_array, int size)

 

# create the wrapper code, with numpy type annotations

def cos_doubles_func(np.ndarray[double, ndim=1, mode="c"] in_array not None,

                     np.ndarray[double, ndim=1, mode="c"] out_array not None):

    cos_doubles(<double*> np.PyArray_DATA(in_array),

                <double*> np.PyArray_DATA(out_array),

                in_array.shape[0])


setup.py


from distutils.core import setup, Extensionimport numpyfrom Cython.Distutils import build_ext

 

setup(

    cmdclass={'build_ext': build_ext},

    ext_modules=[Extension("cos_doubles",

                 sources=["_cos_doubles.pyx", "cos_doubles.c"],

                 include_dirs=[numpy.get_include()])],

)


编译打包


在命令行窗口中进入到上述文件所在同级目录,输入:


>> python setup.py build_ext -i


参数-i表示inplace,即在同级目录下生成Python可调用模块pyd文件。

 

build过程如下:


build过程

 

然后可以看见在同级目录下多了两个文件:


_cos_doubles.c,使用Python C-API自动包装生成的C文件。

cos_doubles.pyx,Python可直接调用的module文件,也就是最终我们所需要的东西。


接下来测试一下:


# file: test.py

import cos_doubles

import numpy as np

import matplotlib.pyplot as plt

 

a = np.linspace(-5, 5, 100)

b = np.empty_like(a)

cos_doubles.cos_doubles_func(a, b)

 

plt.plot(b)

plt.show

()


运行效果如下图所示:

 


运行效果


参考资料

[1] SciPy lecture notes: 2.8. Interfacing with C


[2] Working with NumPy


[3] Python中使用C代码:以NumPy为例 


[4] Cython学习

 

原文链接:http://www.jianshu.com/p/1918e580581d


查阅更为简洁方便的分类文章以及最新的课程、产品信息,请移步至全新呈现的“LeadAI学院官网”:

www.leadai.org


请关注人工智能LeadAI公众号,查看更多专业文章

大家都在看

LSTM模型在问答系统中的应用

基于TensorFlow的神经网络解决用户流失概览问题

最全常见算法工程师面试题目整理(一)

最全常见算法工程师面试题目整理(二)

TensorFlow从1到2 | 第三章 深度学习革命的开端:卷积神经网络

装饰器 | Python高级编程

今天不如来复习下Python基础



点击“阅读原文”直接打开报名链接