听了师兄的建议,以后要是还有什么自己好不容易做出来的东西一定要把过程记下来。
为了提高代码的速度,在已有算法不能再快的情况下【我是认为快不了了】,在看了“Cython 三分钟入门”后,我决定用Cython。
首先是安装,中间老是出各种问题,弄了将近两天总算搞清楚了。
第一步,
去官网下载Cython:www.cython.org
虽然官网推荐Windows用户用Python(x,y),内部自带了Cython,但是设置还是要自己手动完成。于是就直接去安装了Cython。
第二步,
下载MinGW。如果不安装,就有可能在安装的时候出现“Unable to find vcvarsall.bat” 的问题【这一步困了好久,后来看一些文章安装了VS2008也没用】。而且Cython的安装中有提示需要安装(http://docs.cython.org/src/tutorial/appendix.html?highlight=mingw),因为MinGW是个gcc的编译器(?)。跟着Cython的建议下载了MinGW【注意是下载mingw-get-setup.exe】,并且将C:\MinGW\bin和C:\MinGW\lib加入了环境变量,而且自己写了文件“c:\Python26\Lib\distutils\distutils.cfg”,内容如下:
[build]
compiler = mingw32
但是万恶的,Cython在安装的时候还是出错了!
这回说“Command ‘gcc’ failed: no such file or directory”!
第三步,
上网看了这个问题的一些方法,后来发现一篇文章"stackoverflow.com/questions/17972347/error-command-gcc-failed-no-such-file-or-directorya",说还要下载gcc-mingw-4.3.3-setup.exe(https://github.com/develersrl/gccwinbinaries),于是又下载了这个。这下没问题了!
在Cython安装目录下用python setup.py install 成功安装后进行测试。
测试:
在Cython安装目录下有个Demos文件夹,在此目录下输入命令行python setup.py build_ext --inplace,不报错以后。再运行python run_primes.py,成功出现一个全是数的list就算成功啦!
鉴于我是为了提高随机模拟生成序列的速度选了Cython,我亲自写了两个函数,一个是Cython的,一个是Python的:
使用Cython之前需要写一个做模块的setup.py文件:
#-*-coding:gbk-*-
# Run as:
# python setup.py build_ext --inplace
import sys
sys.path.insert(0, "..")
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
ext_modules = cythonize("Simulate.pyx")
setup(
ext_modules = ext_modules,
)
用python setup.py build_ext --inplace运行后,Simulate就是一个模块啦。可以用import导入python文件。Simulate.pyx文件:
def Simulate_Seq(seq, accu_aa_prob, aa_type):
simulate_seq={}#key:seq,value:number of seq
cdef int k
cdef int i
cdef int j
cdef float n
for k from 0 <= k < 10000000:
if k%1000000==0:
print ".",
nseq=""
seq_len=len(seq)
for i in range(seq_len):
n=random.random()
for j from 0 <= j < 20:
if n<=accu_aa_prob[seq[i]][j]:
nseq+=aa_type[j]
break
if not nseq in simulate_seq:
simulate_seq[nseq]=1
else:
simulate_seq[nseq]+=1
return simulate_seq
测试代码:
#-*-coding:gbk-*-
import time,random
from Simulate import Simulate_Seq
aa_type="ACEDGFIHKMLNQPSRTWVY"
accu_aa_prob={'A': [0.89799998344114762, 0.89801638075357149, 0.90782946083716309, 0.91756883913709641, ...... 0.086764834202274085,\
0.092926227584893814, 0.094074936566225828, 0.094123326700468038, 0.094238783409272331, 0.094285231580115286, 1.0]}
seq="NNSSNNS"
Start=time.time()
simulate_seq=Simulate_Seq(seq, accu_aa_prob, aa_type)
End=time.time()
print "Cython:",End-Start
def Simulate_Seq_py(seq, accu_aa_prob, aa_type):
for k in xrange(10000000):#模拟一千万次1000w,10w,100w
if k%1000000==0:
print ".",
nseq=""
for aa in seq:
length_accu_aa_prob=len(accu_aa_prob[aa])
n=random.random()
for i in xrange(length_accu_aa_prob):
if n<=accu_aa_prob[aa][i]:
nseq+=aa_type[i]
break
if nseq not in simulate_seq:
simulate_seq[nseq]=1
else:
simulate_seq[nseq]+=1
return simulate_seq
Start=time.time()
simulate_seq1=Simulate_Seq_py(seq, accu_aa_prob, aa_type)
End=time.time()
print "Python:",End-Start
对一条序列根据字母间的转移概率矩阵,随机模拟1000,0000条序列结果为:
Cython的时间少了一半!