快速教程:使用Cython來擴展Python/NumPy庫
作者:monitor1379
原文鏈接:http://www.jianshu.com/p/1918e580581d
正文共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"n#include <math.h>nn/* Compute the cosine of each element in in_array, storing the result inn* out_array. */nvoid cos_doubles(double * in_array, double * out_array, int size){n int i;n for(i=0;i<size;i++){n out_array[i] = cos(in_array[i]);n }n}n
cos_doubles.h
#ifndef _COS_DOUBLES_Hnn#define _COS_DOUBLES_Hnvoid cos_doubles(double * in_array, double * out_array, int size);n#endifn
cos_doubles.pyx
""" Example of wrapping a C function that takes C double arrays as input usingnn the Numpy declarations from Cython """nn# import both numpy and the Cython declarations for numpynimport numpy as npncimport numpy as npnn# if you want to use the Numpy-C-API from Cythonn# (not strictly necessary for this example)nnp.import_array()nn# cdefine the signature of our c functionncdef extern from "cos_doubles.h":n void cos_doubles (double * in_array, double * out_array, int size)nn# create the wrapper code, with numpy type annotationsndef cos_doubles_func(np.ndarray[double, ndim=1, mode="c"] in_array not None,n np.ndarray[double, ndim=1, mode="c"] out_array not None):n cos_doubles(<double*> np.PyArray_DATA(in_array),n <double*> np.PyArray_DATA(out_array),n in_array.shape[0])n
setup.py
from distutils.core import setup, Extensionimport numpyfrom Cython.Distutils import build_extnnsetup(n cmdclass={build_ext: build_ext},n ext_modules=[Extension("cos_doubles",n sources=["_cos_doubles.pyx", "cos_doubles.c"],n include_dirs=[numpy.get_include()])],n)n
編譯打包
在命令行窗口中進入到上述文件所在同級目錄,輸入:
>> python setup.py build_ext -i
參數-i表示inplace,即在同級目錄下生成Python可調用模塊pyd文件。
build過程如下:
然後可以看見在同級目錄下多了兩個文件:
_cos_doubles.c,使用Python C-API自動包裝生成的C文件。
cos_doubles.pyx,Python可直接調用的module文件,也就是最終我們所需要的東西。
接下來測試一下:
# file: test.pynimport cos_doublesnimport numpy as npnimport matplotlib.pyplot as pltnna = np.linspace(-5, 5, 100)nb = np.empty_like(a)ncos_doubles.cos_doubles_func(a, b)nnplt.plot(b)nplt.shown()n
運行效果如下圖所示:
參考資料
[1] SciPy lecture notes: 2.8. Interfacing with C
[2] Working with NumPy
[3] Python中使用C代碼:以NumPy為例
[4] Cython學習
推薦閱讀:
TAG:Python |