我知道Cythons的目的是什么.它是用类似Python的语言编写可编译的C扩展,以便在代码中产生加速.我想知道(并且似乎找不到使用我的google-fu)是因为Cython可以以某种方式编译成可执行格式,因为它似乎已经将python代码分解为C.
我已经使用了Py2Exe,它只是一个打包器,但我有兴趣使用它来编译一些有点难以解压缩的东西(任何使用Py2EXE打包的东西基本上只能使用我不想要的7zip提取)
看来,如果这是没有可能的我的下一个替代办法只是编译我的所有代码并加载它作为一个模块,然后,使用py2exe至少获得包装大多数我的代码为编译形式,对不对?
为什么 np.dot 比 np.sum 快这么多?根据这个答案,我们知道 np.sum 很慢并且有更快的替代方案。
\n例如:
\nIn [20]: A = np.random.rand(1000)\n\nIn [21]: B = np.random.rand(1000)\n\nIn [22]: %timeit np.sum(A)\n3.21 \xc2\xb5s \xc2\xb1 270 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 100,000 loops each)\n\nIn [23]: %timeit A.sum()\n1.7 \xc2\xb5s \xc2\xb1 11.5 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 1,000,000 loops each)\n\nIn [24]: %timeit np.add.reduce(A)\n1.61 \xc2\xb5s \xc2\xb1 19.6 ns per loop (mean \xc2\xb1 std. dev. of 7 runs, 1,000,000 loops each)\n
Run Code Online (Sandbox Code Playgroud)\n但它们都比以下慢: …
我想通过使用BLAS和LAPACK在C或C++中编写一些模块来扩展python和numpy.我还希望能够将代码作为独立的C/C++库进行分发.我希望这个库使用单精度和双精度浮点数.我将编写的函数的一些示例是用于求解线性系统或加速一阶方法的共轭梯度.有些函数需要从C/C++代码调用Python函数.
在使用Python/C API和Numpy/C API稍微玩了一下之后,我发现许多人主张使用Cython(例如参见这个问题或者这个问题).我不是Cython的专家,但似乎在某些情况下,你仍然需要使用Numpy/C API并知道它是如何工作的.鉴于我已经拥有(一些)关于Python/C API的知识而没有关于Cython的知识,我想知道继续使用Python/C API是否有意义,并且如果使用此API比Cython有一些优势.在未来,我肯定会开发一些不涉及数值计算的东西,所以这个问题不仅仅是关于numpy.我喜欢Python/C API的一个原因是我学到了一些关于Python解释器如何工作的东西.
谢谢.
我刚刚使用Cython将我的C库的一部分编译为扩展,作为"概念证明".我设法破解了代码(const纠正问题等),最终得到了一个扩展.
但是,当我尝试导入新创建的扩展时,我收到以下错误:
ImportError: dynamic module does not define init function
Run Code Online (Sandbox Code Playgroud)
我做错了什么,如何解决这个问题?
我在Ubuntu 10.0.4上使用Cythn 0.11.2和Python 2.6.5
我目前使用Cython链接C和Python,并在慢速的python代码中获得加速.但是,我想使用goroutine来实现一个非常慢(并且非常可并行化)的代码,但它必须可以从python中调用.(我已经看过这个问题)
我(在某种程度上)乐意通过C(或用Cython)去,如果需要建立数据结构等,但避免这种额外的层将是从一个bug修复/避让点好.
无需重新发明轮子,最简单的方法是什么?
我有很多C函数,我想从python中调用它们.cython似乎是要走的路,但我无法真正找到一个如何做到这一点的例子.我的C函数看起来像这样:
void calculate_daily ( char *db_name, int grid_id, int year,
double *dtmp, double *dtmn, double *dtmx,
double *dprec, double *ddtr, double *dayl,
double *dpet, double *dpar ) ;
Run Code Online (Sandbox Code Playgroud)
我想要做的就是指定前三个参数(一个字符串和两个整数),并恢复8个numpy数组(或python列表.所有双数组都有N个元素).我的代码假设指针指向已经分配的内存块.此外,生成的C代码应该链接到一些外部库.
在我的安装中,numpy arrayobject.h
位于…/site-packages/numpy/core/include/numpy/arrayobject.h
.我写了一个使用numpy的简单Cython脚本:
cimport numpy as np
def say_hello_to(name):
print("Hello %s!" % name)
Run Code Online (Sandbox Code Playgroud)
我也有以下distutils setup.py
(从Cython用户指南复制):
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules = [Extension("hello", ["hello.pyx"])]
setup(
name = 'Hello world app',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules
)
Run Code Online (Sandbox Code Playgroud)
当我尝试构建时python setup.py build_ext --inplace
,Cython尝试执行以下操作:
gcc -fno-strict-aliasing -Wno-long-double -no-cpp-precomp -mno-fused-madd \
-fno-common -dynamic -DNDEBUG -g -Os -Wall -Wstrict-prototypes -DMACOSX \
-I/usr/include/ffi -DENABLE_DTRACE -arch i386 -arch ppc -pipe \
-I/System/Library/Frameworks/Python.framework/Versions/2.5/include/python2.5 …
Run Code Online (Sandbox Code Playgroud) 我刚遇到Cython,而我正在寻找优化Python代码的方法.我在stackoverflow,python wiki上阅读了各种帖子,并阅读了文章"优化的一般规则".
Cython是最能引起我兴趣的东西; 而不是为自己编写C代码,您可以选择在python代码本身中使用其他数据类型.
这是我试过的一个愚蠢的测试,
#!/usr/bin/python
# test.pyx
def test(value):
for i in xrange(value):
i**2
if(i==1000000):
print i
test(10000001)
Run Code Online (Sandbox Code Playgroud)
$ time python test.pyx
real 0m16.774s
user 0m16.745s
sys 0m0.024s
Run Code Online (Sandbox Code Playgroud)
$ time cython test.pyx
real 0m0.513s
user 0m0.196s
sys 0m0.052s
Run Code Online (Sandbox Code Playgroud)
现在,老实说,我傻眼了.我在这里使用的代码是纯python代码,我所有改变的是解释器.在这种情况下,如果cython这样好,那么为什么人们仍然使用传统的Python解释器呢?Cython有任何可靠性问题吗?
在Cython中处理复杂数字的正确方法是什么?
我想用dtype np.complex128的numpy.ndarray编写一个纯C循环.在Cython中,关联的C类型定义
Cython/Includes/numpy/__init__.pxd
为
ctypedef double complex complex128_t
Run Code Online (Sandbox Code Playgroud)
所以看起来这只是一个简单的C双复合体.
但是,很容易获得奇怪的行为.特别是,有了这些定义
cimport numpy as np
import numpy as np
np.import_array()
cdef extern from "complex.h":
pass
cdef:
np.complex128_t varc128 = 1j
np.float64_t varf64 = 1.
double complex vardc = 1j
double vard = 1.
Run Code Online (Sandbox Code Playgroud)
这条线
varc128 = varc128 * varf64
Run Code Online (Sandbox Code Playgroud)
可以通过Cython编译,但gcc无法编译生成的C代码(错误是"testcplx.c:663:25:错误:声明说明符中的两个或更多数据类型",似乎是由于该行typedef npy_float64 _Complex __pyx_t_npy_float64_complex;
).此错误已经报告(例如此处)但我没有找到任何好的解释和/或清洁解决方案.
没有包含complex.h
,没有错误(我猜因为typedef
那时不包括在内).
但是,仍然存在一个问题,因为在生成的html文件中cython -a testcplx.pyx
,该行varc128 = varc128 * varf64
是黄色的,这意味着它尚未被转换为纯C.相应的C代码是:
__pyx_t_2 = __Pyx_c_prod_npy_float64(__pyx_t_npy_float64_complex_from_parts(__Pyx_CREAL(__pyx_v_8testcplx_varc128), __Pyx_CIMAG(__pyx_v_8testcplx_varc128)), __pyx_t_npy_float64_complex_from_parts(__pyx_v_8testcplx_varf64, 0));
__pyx_v_8testcplx_varc128 …
Run Code Online (Sandbox Code Playgroud) 我有一个分析代码,使用numpy进行一些繁重的数值运算.只是为了好奇,尝试用cython编译它几乎没有变化,然后我用循环为numpy部分重写它.
令我惊讶的是,基于循环的代码要快得多(8x).我不能发布完整的代码,但我把一个非常简单的无关计算放在一起,显示出类似的行为(虽然时间差异不是很大):
版本1(没有cython)
import numpy as np
def _process(array):
rows = array.shape[0]
cols = array.shape[1]
out = np.zeros((rows, cols))
for row in range(0, rows):
out[row, :] = np.sum(array - array[row, :], axis=0)
return out
def main():
data = np.load('data.npy')
out = _process(data)
np.save('vianumpy.npy', out)
Run Code Online (Sandbox Code Playgroud)
版本2(使用cython构建模块)
import cython
cimport cython
import numpy as np
cimport numpy as np
DTYPE = np.float64
ctypedef np.float64_t DTYPE_t
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.nonecheck(False)
cdef _process(np.ndarray[DTYPE_t, ndim=2] array):
cdef unsigned int rows = array.shape[0]
cdef unsigned int cols …
Run Code Online (Sandbox Code Playgroud) cython ×10
python ×10
numpy ×6
c ×3
performance ×2
compilation ×1
distutils ×1
go ×1
numba ×1
simd ×1