作者painkiller (肚子饿~)
看板Python
标题[心得] Scipy+Numpy,在Python里面使用C语言
时间Sat Apr 9 08:09:05 2011
最近开始用python进行一些数据分析...
想跟各位分享一下 使用Scipy + Numpy 将 C语言整合至python的心得:
python在某些情况下的速度实在是让人无法忍受
(ex. 对大型List做两三层回圈以上的数学运算)
为了增强python在这方面的功能
有两个好用的module: SciPy & Numpy
numpy 基本上是使用自订的 "array"
相较於python list, numpy array里的元素资料型态是一致的
所以在记忆体的使用上有较高效率
而且内建的 "universal function" (ufunc)功能
可以一次对整个numpy array做简单的数学函数运算
可惜如果运算稍微复杂一点时,
numpy 提供的 frompython (将自订函数转成universal function)
相较於使用python本身去写并没有快多少
速度上还是不如C语言
这个时候Scipy就可以出场了...
Scipy本身的功能也相当强大,比如说scipy.matplotlib用来绘图就蛮方便的
其中的scipy.weave更提供了直接在python 里面使用C语言(and C++)的功能:
举例来说, hello world:
from scipy import weave
code="""printf("Hello World! \\n");"""
weave.inline(code)
当然, 这看起来像脱裤子放屁 XD
不过如果有一个或好几个很长的numpy array,
就可以用weave.blitz
结合weave.inline 直接传到在python里面写的C code里
举例:
import numpy as np
from scipy import weave
a=np.arange(0,1000,dtype=float).reshape(500,2)
#产生((0,1),(2,3),(4,5)...(998,999))的500*2矩阵,并指定资料型态为float
code="""
float k=0.0;
for(int i=0;i<500;i++)
{
k+=a(i,0)+a(i,1); //直接在code里面使用刚刚产生的矩阵
}
return Py_BuildValue("d", k); //传回一个float给python
"""
print weave.inline(code,
['a'],
type_converters=weave.converters.blitz,
compiler='gcc')
就会出现从0 加到 999的值罗
如果要传回python list,
可以在C code里宣告
ex.
PyObject *m = PyList_New(0);
对这个list 可以像在python 里面一样操作,
如: PyList_Append(m, PyFloat_FromDouble(k));
因为是在C语言里面,所以资料型态要指定好
关於如何增加python的效率, 有兴趣的人可以看看这边
http://www.scipy.org/PerformancePython
个人是觉得简单但是大量的运算
用weave.inline 搭配 numpy, weave.blitz是相当方便的组合
cython or SWIG速度比inline快上一点, 但是使用上稍微复杂一些(对我来说 XD)
如果是使用windows的话 python(x,y)装了就可以直接用scipy.weave & numpy了
用linux的话就是手动装scipy & numpy,
要使用weave的话得多装python-dev
还有要更改这个
/usr/lib/python2.6/dist-packages/scipy/weave/blitz/blitz/blitz.h
在#include <stdio.h> 之前添加:
#include <cstdlib>
以上抛砖引玉
希望有更多高手可以分享使用python 做科学研究的心得 ~OTZ
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 129.170.26.186
※ 编辑: painkiller 来自: 129.170.26.186 (04/09 08:20)
※ 编辑: painkiller 来自: 129.170.26.186 (04/09 08:21)
2F:推 pcedison:感谢分享 04/09 08:30
3F:推 curist:推推 04/09 18:09
4F:推 mjsg:感谢分享 04/09 20:04
5F:推 cobrasgo:如果是我的话,重点应该会放在那两三层的回圈有没有办法 04/10 15:49
6F:→ cobrasgo:改写逻辑 04/10 15:49
7F:→ painkiller:嗯...大概是我举得例不好 光是取sin值100万次的话 04/10 22:33
8F:→ painkiller:python就比weave慢个10倍左右 04/10 22:33
9F:推 guteres:请问有没有办法把code另外存成档案再去call它? 04/11 00:07
10F:→ painkiller:可能要用SWIG之类的套件喔... 那个我很不熟耶 :P 04/11 22:33
11F:推 guteres:soga 04/13 00:13
12F:推 cobrasgo:用c binding不就可以了? 04/13 00:52