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

前言

整个快速教程直接上例子,具体对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学习

原文发布于微信公众号 - 人工智能LeadAI(atleadai)

原文发表时间:2017-12-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏炸天帮5

win32进程概念之句柄表,以及内核对象.

我们知道.我们使用CreateProcess 的时候会返回一个进程句柄.以及线程句柄. 其实在调用CreateProcess的时候.内核中会新建一个EPROCE...

711
来自专栏钟绍威的专栏

linux常用命令之查阅文件用法选项功能键用法选项DEMO用法选项选项注意选项注意选项注意用法选项

CAT cat – concatenate print files 连续的输出文件内容 用法 cat [-nbA] file 选项 -n line number...

1905
来自专栏青玉伏案

iOS开发之再探多线程编程:Grand Central Dispatch详解

Swift3.0相关代码已在github上更新。之前关于iOS开发多线程的内容发布过一篇博客,其中介绍了NSThread、操作队列以及GCD,介绍的不够深入。今...

1917
来自专栏Java架构

Java并发之Condition的实现分析

回忆 synchronized 关键字,它配合 Object 的 wait()、notify() 系列方法可以实现等待/通知模式。

682
来自专栏流柯技术学院

LoadRunner上传及下载文件

         web_submit_data("importStudent.do",

2192
来自专栏IMWeb前端团队

上手 yeoman generator

最近折腾脚手架相关的一些事情。说到脚手架,不得不谈的就是yeoman了。 是什么 yeoman是一个脚手架生成工具。 yeoman generator则是yeo...

2185
来自专栏orientlu

python 配置文件读写

将代码中的配置项抽取到配置文件中,修改配置时不需要涉及到代码修改,避免面对一堆令人抓狂的 magic number,极大的方便后期软件的维护。

2833
来自专栏difcareer的技术笔记

Android Inline Hook 详解前言原理分析

网上有几篇关于Android inline hook的文章,这篇尤其不错,还有对应的示例代码。为了方便调试看结果,我将其改为gradle工程,代码见这里。你需要...

1372
来自专栏数据科学与人工智能

IPython使用简易教程

本文总结Ipython使用的知识。 ? 1 IPython 是什么? IPython (short for Interactive Python) was st...

3994
来自专栏linux驱动个人学习

VFS四大对象之二 struct inode

继上一篇文章:https://cloud.tencent.com/developer/article/1053842 二、inode结构体:(转自http://...

5297

扫码关注云+社区