Python 使用Cython获得更快的numpy函数

Python 使用Cython获得更快的numpy函数,python,performance,numpy,cython,Python,Performance,Numpy,Cython,我正在尝试优化我的代码,它大量使用numpy函数。我在这里创建了一个简单的版本 #pythonic.py 将numpy作为np导入 def numpyWithPython(): a=np.random.randint(10,大小=5000)-5 b=a[a>0] c=np.cumprod(b) d=np.diff(c,前置=0) e=np.乘(d,b) f=e.copy() f[f>1]=2 g=np.圆形(f*5000) 如果np.和(g)>0: 返回np.和(g) 其他: 返回20 所以基

我正在尝试优化我的代码,它大量使用numpy函数。我在这里创建了一个简单的版本

#pythonic.py
将numpy作为np导入
def numpyWithPython():
a=np.random.randint(10,大小=5000)-5
b=a[a>0]
c=np.cumprod(b)
d=np.diff(c,前置=0)
e=np.乘(d,b)
f=e.copy()
f[f>1]=2
g=np.圆形(f*5000)
如果np.和(g)>0:
返回np.和(g)
其他:
返回20
所以基本上整个函数都与numpy一起工作。然后我将其编译为Cython,我尽了最大努力进行优化,但我不确定,无论如何,代码如下所示:

#Cythonic.pyx
import numpy as np
cimport numpy as np

# cython: boundscheck=False
# cython: cdivision=True
# cython: wraparound=False

cpdef int numpyWithCython():
        cdef np.ndarray[long, ndim=1, mode='c'] a = np.random.randint(10, size=5000) -5
        cdef np.ndarray[long, ndim=1, mode='c'] b = a[a>0]
        cdef np.ndarray[long, ndim=1, mode='c'] c = np.cumprod(b)
        cdef np.ndarray[long, ndim=1, mode='c'] d = np.diff(c, prepend=0)
        cdef np.ndarray[long, ndim=1, mode='c'] e= np.multiply(d,b)
        cdef np.ndarray[long, ndim=1, mode='c'] f=e.copy()
        f[f >1] =2
        cdef np.ndarray[long, ndim=1, mode='c'] g =np.round(f*5000)

        if np.sum(g)>0:
                return np.sum(g)
        else:
                return 20
让我们来比较一下

来自pythonic import numpywhithpython
来自Cythonic import numpyWithCython
导入时间信息
py=timeit.timeit(numpyWithPython,number=1000)
打印(“Python:,py)
cy=timeit.timeit(numpyWithCython,number=1000)
打印(“Cyhton:,cy)
比我得到的每一个负面的改善,这是意想不到的

Python:0.2221166321079613 >>>Cyhton:0.23356160436067247 我对Cython的优化是错误的还是在这种情况下Numpy已经很快了,所以Cython毫无意义


我应该使用本机python数组来加快速度,还是我可以做些什么来加快速度?

对于可能对加快速度感兴趣的人,我从pandas.DataFrame开始,然后我使用pandas.Series获得了2倍于Numpy版本的效果,甚至比Numpy版本快了4倍。我还可以共享setup.py来展示我是如何编译到CythonMost numpy的功能是高度优化的编译c代码。如果你能加快neyond的速度,我会非常惊讶。在上面查找
annotate=True
,它会告诉你Cython代码转换到C的效果如何,如果有瓶颈,另请看,您真正做的只是添加了一些无意义的类型检查,Cython确保参数是Numpy数组-这就是为什么速度较慢的原因。如果您需要加快代码速度,则需要放弃Numpy函数调用。您不想创建6个中间numpy数组;为每个数据分配内存并存储所有这些数据会降低速度。尝试在每个元素上进行for循环运算,并一次执行1个元素的所有数学运算。对于可能对超速感兴趣的人,我从pandas.DataFrame开始,然后我使用pandas.Series获得了约2倍的效果。与Numpy版本相比,Series甚至快了约4倍。我还可以共享setup.py来展示我是如何编译到CythonMost numpy的功能是高度优化的编译c代码。如果你能加快neyond的速度,我会非常惊讶。在上面查找
annotate=True
,它会告诉你Cython代码转换到C的效果如何,如果有瓶颈,另请看,您真正做的只是添加了一些无意义的类型检查,Cython确保参数是Numpy数组-这就是为什么速度较慢的原因。如果您需要加快代码速度,则需要放弃Numpy函数调用。您不想创建6个中间numpy数组;为每个数据分配内存并存储所有这些数据会降低速度。尝试在for循环中对每个元素进行操作,并一次对一个元素执行所有数学操作。