【发布时间】:2019-04-11 15:03:17
【问题描述】:
我正在寻找加快 python numpy 代码的速度:
def fun_np(m,data):
a, b, c = data[:,0], data[:,1], data[:,2]
M = len(data[:,0])
n = round((m+1)*(m+2)*(m+3)/6)
u =np.zeros((M,n))
C = 0
for i in range(0,m+1):
for j in range(0,i+1):
for k in range(0,j+1):
if ((i-j)!=0):
u[:,C] = (j-k)*(a)**(i-j)*(b)**(j-k-1)*(c)**k
C=C+1
return u
对应的cython代码如下:
%%cython
import numpy as np
cimport numpy as np
from cython import wraparound, boundscheck, nonecheck
@boundscheck(False)
@wraparound(False)
@nonecheck(False)
cpdef fun_cyt(int m,np.ndarray[np.float64_t, ndim=2] data):
cdef:
np.ndarray[np.float64_t, ndim=1] a = data[:,0]
np.ndarray[np.float64_t, ndim=1] b = data[:,1]
np.ndarray[np.float64_t, ndim=1] c = data[:,2]
int M, n
Py_ssize_t i, j, k, s
M = len(data[:,0])
n = round((m+1)*(m+2)*(m+3)/6)
cdef np.ndarray[np.float64_t, ndim=2] u = np.zeros((M,n), dtype=np.float64)
cdef int C = 0
for i in range(m+1): #range(0,m+1):
for j in range(i+1):
for k in range(j+1):
for s in range(M):
if (i-j)!=0:
u[s,C] = (j-k)*(a[s])**(i-j)*(b[s])**(j-k-1)*(c[s])**k
C=C+1
return u
这里是时间
z = np.random.randn(6000, 3); m=20;
%timeit fun_np(m,z);
结果:每个循环 1.97 秒 ± 11.2 毫秒(平均值 ± 标准偏差,7 次运行,每次 1 个循环)
%timeit fun_cyt(m,z);
结果:每个循环 1.91 秒 ± 12.7 毫秒(平均值 ± 标准偏差,7 次运行,每个循环 1 个)
如您所见,numpy 和 cython 代码之间没有显着的速度。如果可能的话,如果您能帮助优化 cython 代码,我将不胜感激。
cython 代码的注释 html html
【问题讨论】:
-
如果您正在寻找代码审查,请在 codereview.stackexchange.com 上试试运气,因为您的问题不在 StackOverflow 上。
-
@HIlle 不 - 没有理由在这里偏离主题。我想说它属于the help“特定编程问题”中列出的第一个要点。事实上,它也可能在代码审查中成为主题,但这并不意味着它在这里是离题的。
-
@ForBonder 你看过带注释的 html 输出(来自运行
cython -a yourfile.pyx)吗?如果您遗漏了什么,它通常可以为您提供线索 -
@DavidW 谢谢,我查看了带注释的 html,但没有提前。我已经添加了带注释的 html 的链接。
-
看起来不错。这是 Cython 非常擅长的问题,而且看起来你做了正确的事情,所以你没有看到差异有点令人惊讶。
标签: python performance numpy optimization cython