前言

本节不具体讲解cython的原理和细节,提供一个最简单的例子,将一个python代码转化为一个cython代码,同时由于本人对cython刚入门,只会一个简单的操作,即在cython中声明变量的类型。实验证明,就这样简单添加变量类型,代码运行速度提升了将近4倍
cython对于代码中许多循环的情况很有帮助!

python代码

这里给的是CVPPP官方提供的evaluate代码(evaluate.py)
为了节省空间,这里删除了注释和一些无关紧要的判断语句

import numpy as np
def DiffFGLabels(inLabel,gtLabel):maxInLabel = np.int(np.max(inLabel))minInLabel = np.int(np.min(inLabel))maxGtLabel = np.int(np.max(gtLabel))minGtLabel = np.int(np.min(gtLabel))return  (maxInLabel-minInLabel) - (maxGtLabel-minGtLabel) def BestDice(inLabel,gtLabel):score = 0maxInLabel = np.max(inLabel) minInLabel = np.min(inLabel) maxGtLabel = np.max(gtLabel) minGtLabel = np.min(gtLabel) if(maxInLabel==minInLabel):return scorefor i in range(minInLabel+1,maxInLabel+1):sMax = 0; for j in range(minGtLabel+1,maxGtLabel+1): s = Dice(inLabel, gtLabel, i, j) if(sMax < s):sMax = sscore = score + sMax; score = score/(maxInLabel-minInLabel)return scoredef FGBGDice(inLabel,gtLabel):minInLabel = np.min(inLabel) minGtLabel = np.min(gtLabel) one = np.ones(inLabel.shape)    inFgLabel = (inLabel != minInLabel*one)*onegtFgLabel = (gtLabel != minGtLabel*one)*onereturn Dice(inFgLabel,gtFgLabel,1,1)def Dice(inLabel, gtLabel, i, j):one = np.ones(inLabel.shape)inMask = (inLabel==i*one) gtMask = (gtLabel==j*one) inSize = np.sum(inMask*one) gtSize = np.sum(gtMask*one) overlap= np.sum(inMask*gtMask*one) if ((inSize + gtSize)>1e-8):out = 2*overlap/(inSize + gtSize) else:out = 0return outdef AbsDiffFGLabels(inLabel,gtLabel):return np.abs( DiffFGLabels(inLabel,gtLabel) )def SymmetricBestDice(inLabel,gtLabel):bd1 = BestDice(inLabel,gtLabel)bd2 = BestDice(gtLabel,inLabel)if bd1 < bd2:return bd1else:return bd2

Cython代码

创建一个evaluate.pyx文件(注意:后缀得是pyx!!!

from __future__ import division
from libcpp cimport bool as bool_t
import numpy as np
cimport numpy as np
cimport cythonctypedef bint TYPE_BOOL
ctypedef unsigned long long TYPE_U_INT64
ctypedef unsigned int TYPE_U_INT32
ctypedef unsigned short TYPE_U_INT16
ctypedef unsigned char TYPE_U_INT8
ctypedef long long TYPE_INT64
ctypedef int TYPE_INT32
ctypedef short TYPE_INT16
ctypedef signed char TYPE_INT8
ctypedef float TYPE_FLOAT
ctypedef double TYPE_DOUBLE@cython.boundscheck(False) # turn off bounds-checking for entire function
@cython.wraparound(False)  # turn off negative index wrapping for entire function
def DiffFGLabels(np.ndarray[TYPE_U_INT16, ndim=2] inLabel, np.ndarray[TYPE_U_INT16, ndim=2] gtLabel):cdef int maxInLabel = np.int(np.max(inLabel)) cdef int minInLabel = np.int(np.min(inLabel)) cdef int maxGtLabel = np.int(np.max(gtLabel)) cdef int minGtLabel = np.int(np.min(gtLabel)) cdef double out = (maxInLabel-minInLabel) - (maxGtLabel-minGtLabel)return out@cython.boundscheck(False)
@cython.wraparound(False)
def BestDice(np.ndarray[TYPE_U_INT16, ndim=2] inLabel, np.ndarray[TYPE_U_INT16, ndim=2] gtLabel):cdef int i, jcdef double sMax = 0.0cdef double s = 0.0cdef double score = 0.0 cdef int maxInLabel = np.max(inLabel) cdef int minInLabel = np.min(inLabel) cdef int maxGtLabel = np.max(gtLabel) cdef int minGtLabel = np.min(gtLabel) if(maxInLabel == minInLabel): return scorefor i in range(minInLabel+1, maxInLabel+1):sMax = 0;for j in range(minGtLabel+1, maxGtLabel+1):s = Dice(inLabel, gtLabel, i, j) if(sMax < s):sMax = sscore = score + sMax;score = score / (maxInLabel-minInLabel)return score@cython.boundscheck(False)
@cython.wraparound(False)
def FGBGDice(np.ndarray[TYPE_U_INT16, ndim=2] inLabel, np.ndarray[TYPE_U_INT16, ndim=2] gtLabel):cdef int minInLabel = np.min(inLabel) cdef int minGtLabel = np.min(gtLabel) cdef np.ndarray[TYPE_U_INT16, ndim=2] one = np.ones_like(inLabel)cdef np.ndarray[TYPE_U_INT16, ndim=2] inFgLabel = (inLabel != minInLabel*one)*onecdef np.ndarray[TYPE_U_INT16, ndim=2] gtFgLabel = (gtLabel != minGtLabel*one)*onecdef double out = Dice(inFgLabel,gtFgLabel,1,1) return out@cython.boundscheck(False)
@cython.wraparound(False)
def Dice(np.ndarray[TYPE_U_INT16, ndim=2] inLabel, np.ndarray[TYPE_U_INT16, ndim=2] gtLabel, int i, int j):cdef double out = 0.0cdef np.ndarray[TYPE_U_INT16, ndim=2] one = np.ones_like(inLabel)cdef int inSize = np.sum((inLabel==i*one)*one) cdef int gtSize = np.sum((gtLabel==j*one)*one) cdef int overlap= np.sum((inLabel==i*one)*(gtLabel==j*one)*one) if ((inSize + gtSize)>1e-8):out = 2*overlap/(inSize + gtSize) else:out = 0return out@cython.boundscheck(False)
@cython.wraparound(False)
def AbsDiffFGLabels(np.ndarray[TYPE_U_INT16, ndim=2] inLabel, np.ndarray[TYPE_U_INT16, ndim=2] gtLabel):cdef double out = np.abs(DiffFGLabels(inLabel, gtLabel))return out@cython.boundscheck(False)
@cython.wraparound(False)
def SymmetricBestDice(np.ndarray[TYPE_U_INT16, ndim=2] inLabel, np.ndarray[TYPE_U_INT16, ndim=2] gtLabel):cdef double bd1 = BestDice(inLabel,gtLabel)cdef double bd2 = BestDice(gtLabel,inLabel)if bd1 < bd2:return bd1else:return bd2

编译

写好pyx文件后,需要再写一个setup.py文件,里面的内容也很简单(注意修改相应的pyx文件名!!!):

import distutils.core
import Cython.Build
import numpy as np
distutils.core.setup(ext_modules = Cython.Build.cythonize("evaluate.pyx"),include_dirs = [np.get_include()])

编译:

python setup.py build_ext --inplace

编译成功后,就可以正常的 import 里面的函数了

解释

通过对比两个代码,我们可以看出一些规律也可以总结出一些规律

  1. 在导入包的时候,有一句最重要的是:cimport numpy as np,表明使用的是cython接口的numpy。(当然也有import numpy as np,编译器会根据情况使用numpy还是c-numpy);还有一句是:from libcpp cimport bool as bool_t,这是为了使用C语言中的bool类型(这个例子里面没有用到bool类型,可以不用管)
  2. 为数据类型起一个新名字:ctypedef。这个不是必须,但这里为了可读性,我列举了一些numpy中常用的数据类型对应的C语言中的数据类型
numpy C
np.uint8 unsigned char
np.uint16 unsigned short
np.uint32 unsigned int
np.uint64 unsigned long long
np.int8 signed char
np.int16 short
np.int32 int
np.int64 long long
np.float32 double
  1. 每个函数前面都有:@cython.boundscheck(False) 和 @cython.wraparound(False),这是为了加速而关闭边界检查,这样做就需要提前保证代码的准确性,建议在python下验证代码的准确性
  2. 每个函数的输入变量都定义了数据类型,比如这里全是:np.ndarray[TYPE_U_INT16, ndim=2],这表明输入的一个二维的uint16的numpy数组,如果输入类型不是这样,那就会报错
  3. cdef int/double:定义整型/双精度浮点型变量。在使用每个变量须先对它进行定义,如果没有编译器就会花时间来判断,就会耗时

Cython入门:将python代码转为cython相关推荐

  1. python游戏中调整箭头下落速度_入门 | 三行Python代码,让数据预处理速度提高2到6倍...

    原标题:入门 | 三行Python代码,让数据预处理速度提高2到6倍 选自TowardsDataScience 作者:George Seif,机器之心编译 在 Python 中,我们可以找到原生的并行 ...

  2. python代码使用cython进行加密

    python代码加密 前言 加密的多种方式 Cython加密 步骤 注意 部署 前言 加密的多种方式 发布编译过的pyc文件 缺点:很容易被反编译 PyInstaller 是一个用来将 Python ...

  3. jsonarray转化list对象_第8篇:Cython的面向对象--Python类 vs Cython扩展类

    在Python中,一切都是对象. 具体来说是什么意思? 在最基本的层面上,一个对象具有三样东西 标识(id):对象的标识将其与其他对象区分开来,并由id内置函数提供 属性值(value):对象的值就是 ...

  4. 「Python入门」Python代码规范(风格)

    ​ ​ 活动地址:CSDN21天学习挑战赛 文章目录 前言 一.编码规范 二.分号 三.行的最大长度 四. 缩进规则 五.Python注释 5.1 行注释 5.2 块注释 5.3 文档注释 六. Py ...

  5. 分形几何python代码_Python, Cython绘制美妙绝伦的Mandelbrot集, 曼德博集分形图案

    上世纪60-70年代,美籍数学家曼德博 - Benoit B. Mandelbrot几乎单枪匹马的创立了一个新的数学分支,即分形几何学 - fractal geometry.这个新的数学分支有助于人类 ...

  6. cython python3_30倍!使用Cython加速Python代码

    原标题:30倍!使用Cython加速Python代码 作者:George Seif.Thomas Wolf.Lukas Frei 编译:1+1=6 | 公众号海外部 前言 你可能经常会一次又一次地听到 ...

  7. python 大项目使用cython_提升6.75倍!利用Cython为Python代码加速

    全文共2012字,预计学习时长4分钟 图片来源:Unsplash 如果你曾经用Python编写过代码,可能会发现等待某些代码块执行的时间比预期要长.尽管可以通过一些方法提高其代码效率,但它的反应速度仍 ...

  8. 什么是Cython?让Python有C语言的速度

    Python的一个超集,可以编译为C,Cython结合了Python的易用性和原生代码的速度. Python作为最方便,丰富的配置和彻底有用的编程语言之一而享有盛誉. 但执行速度?没那么快. 让我们开 ...

  9. python append函数_让你python代码更快的3个小技巧!速度提高了一倍还多

    大家好!今天呢,我们来聊一聊如何加速你的 python 代码. Python 语言的优点可以列举出许多,语法简单易懂.模块丰富.应用广泛等等.但是世界上没有有完美的东西,python 一个明显缺点就是 ...

最新文章

  1. KMP-next数组
  2. On-Heap与Off-Heap
  3. 通过angular.js实现MVC的基本步骤
  4. 我用python是什么梗_Python中的一些梗
  5. iOS 界面上绘制不同字体 颜色 大小的字符串
  6. tomcat错误:The page you tried to access (/manager/login.do) does not exist
  7. RUP,XP,敏捷原理
  8. C++ STL 线性容器的用法
  9. Keras-Sequential模型(2)
  10. [转载] Python format()格式:中文对齐问题
  11. MySQL 常用基础命令
  12. oracle shared_pool_size 0,Oracle 参数shared_pool_size
  13. VHDL实现交通灯程序
  14. 武汉大学计算机学院推免率,武汉大学保研率
  15. 【编译原理】 CS143 斯坦福大学公开课 第一周:简介
  16. 屏幕录像软件Community Clips Recorder简介及其使用技巧(郝宪玮)
  17. 关于PostgreSQL软件安装后出现解决the application server could not be contect ed错误的方法
  18. 毕业实习感想—软件测试
  19. Odoo隐藏应用模块
  20. flink catalog 及dialect、数据转存分析

热门文章

  1. Oracle CTAS
  2. 《程序员的数学》三部曲
  3. 彻底分清机器学习中的上采样、下采样、过采样、欠采样【总结】
  4. C语言switch语句用法详解
  5. IE浏览器不能上网原因及解决方案
  6. ubuntu系统下THETA S 全景相机 通过ROS导出图像
  7. 基于ICP算法的三维点云数据拼接算法的实现
  8. Android studio下载及安装方法
  9. 第三章,矩阵,04-分块矩阵
  10. C语言:二维数组:求平均数