Skip to main content
 首页 » 编程设计

python之将 Python/Numpy 代码转换为 Cython之数组问题之缓冲区类型仅允许作为函数局部变量

2025年05月04日19lyj

我正在尝试将一些 Python/Numpy 代码转换为 Cython 以加快速度。这是我的代码:

cimport numpy as np 
import numpy as np 
from numpy import * 
import pylab as pl 
from pylab import *  
from scipy import integrate 
 
def myc_rb_e2f(np.ndarray[double,ndim=1] y = np.zeros(7),double t, double k,double d): 
 
    M = y[0] 
    E = y[1] 
    CD = y[2] 
    CE = y[3] 
    R = y[4] 
    RP = y[5]  
    RE = y[6] 
 
    cdef double S = 0.01 
    if t > 300.0: 
        S = 5.0 
    #if t > 400 
        #S = 0.01 
 
    cdef double t1 = k[0]*S/(k[7]+S) 
    cdef double t2 = k[1]*(M/(k[14]+M))*(E/(k[15]+E)) 
    cdef double t3 = k[5]*M/(k[14]+M) 
    cdef double t4 = k[11]*CD*RE/(k[16]+RE) 
    cdef double t5 = k[12]*CE*RE/(k[17]+RE) 
    cdef double t6 = k[2]*M/(k[14]+M) 
    cdef double t7 = k[3]*S/(k[7]+S) 
    cdef double t8 = k[6]*E/(k[15]+E) 
    cdef double t9 = k[13]*RP/(k[18]+RP) 
    cdef double t10 = k[9]*CD*R/(k[16]+R) 
    cdef double t11 = k[10]*CE*R/(k[17]+R) 
 
    dM = t1-d[0]*M 
    dE = t2+t3+t4+t5-k[8]*R*E-d[1]*E 
    dCD = t6+t7-d[2]*CD 
    dCE = t8-d[3]*CE 
    dR = k[4]+t9-k[8]*R*E-t10-t11-d[4]*R 
    dRP = t10+t11+t4+t5-t9-d[5]*RP 
    dRE = k[8]*R*E-t4-t5-d[6]*RE 
 
    dy = [dM,dE,dCD,dCE,dR,dRP,dRE] 
 
    return dy 
 
cdef np.ndarray[double,ndim=1] t = np.zeros(10000) 
t = np.linspace(0.,3000.,10000.) 
 
# Initial concentrations of [M,E,CD,CE,R,RP,RE] 
cdef np.ndarray[double,ndim=1] y0 = np.array([0.,0.,0.,0.,0.4,0.,0.25]) 
cdef np.ndarray[double,ndim=2] E_simulated = np.zeros([10000,5000]) 
cdef np.ndarray[double,ndim=2] r = np.zeros([10000,5000]) 
cdef np.ndarray[double,ndim=1] E_avg = np.zeros([10000]) 
cdef np.ndarray[double,ndim=1] k = np.zeros([19]) 
cdef np.ndarray[double,ndim=1] d = np.zeros([7]) 
cdef int i 
 
for i in range (0,5000): 
    k[0] = 1.+0.1*randn(1) 
    k[1] = 0.15+0.05*randn(1) 
    k[2] = 0.2+0.05*randn(1) 
    k[3] = 0.2+0.05*randn(1) 
    k[4] = 0.35+0.05*randn(1) 
    k[5] = 0.001+0.0001*randn(1) 
    k[6] = 0.5+0.05*randn(1) 
    k[7] = 0.3+0.05*randn(1) 
    k[8] = 30.+5.*randn(1) 
    k[9] = 18.+3.*randn(1) 
    k[10] = 18.+3.*randn(1) 
    k[11] = 18.+3.*randn(1) 
    k[12] = 18.+3.*randn(1) 
    k[13] = 3.6+0.5*randn(1) 
    k[14] = 0.15+0.05*randn(1) 
    k[15] = 0.15+0.05*randn(1) 
    k[16] = 0.92+0.1*randn(1) 
    k[17] = 0.92+0.1*randn(1) 
    k[18] = 0.01+0.001*randn(1) 
    d[0] = 0.7+0.05*randn(1) 
    d[1] = 0.25+0.025*randn(1) 
    d[2] = 1.5+0.05*randn(1) 
    d[3] = 1.5+0.05*randn(1) 
    d[4] = 0.06+0.01*randn(1) 
    d[5] = 0.06+0.01*randn(1) 
    d[6] = 0.03+0.005*randn(1) 
    r = integrate.odeint(myc_rb_e2f,y0,t,args=(k,d)) 
    E_simulated[:,i] = r[:,1] 
 
for i in range(0,10000): 
    E_avg[i] = sum(E_simulated[i,:])/5000. 
 
pl.plot(t,E_avg,'-ro') 
pl.show() 

我在尝试编译时遇到了很多错误:

Error compiling Cython file: 
------------------------------------------------------------ 
... 
 
        dy = [dM,dE,dCD,dCE,dR,dRP,dRE] 
 
        return dy 
 
cdef np.ndarray[double,ndim=1] t = np.zeros(10000) 
                              ^ 
------------------------------------------------------------ 
 
myc_rb_e2f_pyx.pyx:48:31: Buffer types only allowed as function local variables 
 
Error compiling Cython file: 
------------------------------------------------------------ 
... 
 
cdef np.ndarray[double,ndim=1] t = np.zeros(10000) 
t = np.linspace(0.,3000.,10000.) 
 
# Initial concentrations of [M,E,CD,CE,R,RP,RE] 
cdef np.ndarray[double,ndim=1] y0 = np.array([0.,0.,0.,0.,0.4,0.,0.25]) 
                              ^ 
------------------------------------------------------------ 
 
myc_rb_e2f_pyx.pyx:52:31: Buffer types only allowed as function local variables 
 
Error compiling Cython file: 
------------------------------------------------------------ 
... 
cdef np.ndarray[double,ndim=1] t = np.zeros(10000) 
t = np.linspace(0.,3000.,10000.) 
 
# Initial concentrations of [M,E,CD,CE,R,RP,RE] 
cdef np.ndarray[double,ndim=1] y0 = np.array([0.,0.,0.,0.,0.4,0.,0.25]) 
cdef np.ndarray[double,ndim=2] E_simulated = np.zeros([10000,5000]) 
                              ^ 
------------------------------------------------------------ 
 
myc_rb_e2f_pyx.pyx:53:31: Buffer types only allowed as function local variables 
 
Error compiling Cython file: 
------------------------------------------------------------ 
... 
t = np.linspace(0.,3000.,10000.) 
 
# Initial concentrations of [M,E,CD,CE,R,RP,RE] 
cdef np.ndarray[double,ndim=1] y0 = np.array([0.,0.,0.,0.,0.4,0.,0.25]) 
cdef np.ndarray[double,ndim=2] E_simulated = np.zeros([10000,5000]) 
cdef np.ndarray[double,ndim=2] r = np.zeros([10000,5000]) 
                              ^ 
------------------------------------------------------------ 
 
myc_rb_e2f_pyx.pyx:54:31: Buffer types only allowed as function local variables 
 
Error compiling Cython file: 
------------------------------------------------------------ 
... 
 
# Initial concentrations of [M,E,CD,CE,R,RP,RE] 
cdef np.ndarray[double,ndim=1] y0 = np.array([0.,0.,0.,0.,0.4,0.,0.25]) 
cdef np.ndarray[double,ndim=2] E_simulated = np.zeros([10000,5000]) 
cdef np.ndarray[double,ndim=2] r = np.zeros([10000,5000]) 
cdef np.ndarray[double,ndim=1] E_avg = np.zeros([10000]) 
                              ^ 
------------------------------------------------------------ 
 
myc_rb_e2f_pyx.pyx:55:31: Buffer types only allowed as function local variables 
 
Error compiling Cython file: 
------------------------------------------------------------ 
... 
# Initial concentrations of [M,E,CD,CE,R,RP,RE] 
cdef np.ndarray[double,ndim=1] y0 = np.array([0.,0.,0.,0.,0.4,0.,0.25]) 
cdef np.ndarray[double,ndim=2] E_simulated = np.zeros([10000,5000]) 
cdef np.ndarray[double,ndim=2] r = np.zeros([10000,5000]) 
cdef np.ndarray[double,ndim=1] E_avg = np.zeros([10000]) 
cdef np.ndarray[double,ndim=1] k = np.zeros([19]) 
                              ^ 
------------------------------------------------------------ 
 
myc_rb_e2f_pyx.pyx:56:31: Buffer types only allowed as function local variables 
 
Error compiling Cython file: 
------------------------------------------------------------ 
... 
cdef np.ndarray[double,ndim=1] y0 = np.array([0.,0.,0.,0.,0.4,0.,0.25]) 
cdef np.ndarray[double,ndim=2] E_simulated = np.zeros([10000,5000]) 
cdef np.ndarray[double,ndim=2] r = np.zeros([10000,5000]) 
cdef np.ndarray[double,ndim=1] E_avg = np.zeros([10000]) 
cdef np.ndarray[double,ndim=1] k = np.zeros([19]) 
cdef np.ndarray[double,ndim=1] d = np.zeros([7]) 
                              ^ 
------------------------------------------------------------ 
 
myc_rb_e2f_pyx.pyx:57:31: Buffer types only allowed as function local variables 
 
Error compiling Cython file: 
------------------------------------------------------------ 
... 
cimport numpy as np 
^ 
------------------------------------------------------------ 
 
myc_rb_e2f_pyx.pyx:1:0: Buffer vars not allowed in module scope 
An exception has occurred, use %tb to see the full traceback. 
 
SystemExit: error: command 'gcc' failed with exit status 1 
 
 
%run setup.py build_ext --inplace 
running build_ext 
cythoning myc_rb_e2f_pyx.pyx to myc_rb_e2f_pyx.c 
building 'myc_rb_e2f_pyx' extension 
C:\Python27\Scripts\gcc.exe -mno-cygwin -mdll -O -Wall -DMS_WIN64 -IC:\Python27\lib\site-packages\numpy\core\include -IC:\Python27\include -IC:\Python27\PC -c myc_rb_e2f_pyx.c -o build\temp.win-amd64-2.7\Release\myc_rb_e2f_pyx.o 
 
Error compiling Cython file: 
------------------------------------------------------------ 
... 
 
        dy = [dM,dE,dCD,dCE,dR,dRP,dRE] 
 
        return dy 
 
cdef np.ndarray[double,ndim=1] t = np.zeros(10000) 
                              ^ 
------------------------------------------------------------ 
 
myc_rb_e2f_pyx.pyx:48:31: Buffer types only allowed as function local variables 
 
Error compiling Cython file: 
------------------------------------------------------------ 
... 
 
cdef np.ndarray[double,ndim=1] t = np.zeros(10000) 
t = np.linspace(0.,3000.,10000.) 
 
# Initial concentrations of [M,E,CD,CE,R,RP,RE] 
cdef np.ndarray[double,ndim=1] y0 = np.array([0.,0.,0.,0.,0.4,0.,0.25]) 
                              ^ 
------------------------------------------------------------ 
 
myc_rb_e2f_pyx.pyx:52:31: Buffer types only allowed as function local variables 
 
Error compiling Cython file: 
------------------------------------------------------------ 
... 
cdef np.ndarray[double,ndim=1] t = np.zeros(10000) 
t = np.linspace(0.,3000.,10000.) 
 
# Initial concentrations of [M,E,CD,CE,R,RP,RE] 
cdef np.ndarray[double,ndim=1] y0 = np.array([0.,0.,0.,0.,0.4,0.,0.25]) 
cdef np.ndarray[double,ndim=2] E_simulated = np.zeros([10000,5000]) 
                              ^ 
------------------------------------------------------------ 
 
myc_rb_e2f_pyx.pyx:53:31: Buffer types only allowed as function local variables 
 
Error compiling Cython file: 
------------------------------------------------------------ 
... 
t = np.linspace(0.,3000.,10000.) 
 
# Initial concentrations of [M,E,CD,CE,R,RP,RE] 
cdef np.ndarray[double,ndim=1] y0 = np.array([0.,0.,0.,0.,0.4,0.,0.25]) 
cdef np.ndarray[double,ndim=2] E_simulated = np.zeros([10000,5000]) 
cdef np.ndarray[double,ndim=2] r = np.zeros([10000,5000]) 
                              ^ 
------------------------------------------------------------ 
 
myc_rb_e2f_pyx.pyx:54:31: Buffer types only allowed as function local variables 
 
Error compiling Cython file: 
------------------------------------------------------------ 
... 
 
# Initial concentrations of [M,E,CD,CE,R,RP,RE] 
cdef np.ndarray[double,ndim=1] y0 = np.array([0.,0.,0.,0.,0.4,0.,0.25]) 
cdef np.ndarray[double,ndim=2] E_simulated = np.zeros([10000,5000]) 
cdef np.ndarray[double,ndim=2] r = np.zeros([10000,5000]) 
cdef np.ndarray[double,ndim=1] E_avg = np.zeros([10000]) 
                              ^ 
------------------------------------------------------------ 
 
myc_rb_e2f_pyx.pyx:55:31: Buffer types only allowed as function local variables 
 
Error compiling Cython file: 
------------------------------------------------------------ 
... 
# Initial concentrations of [M,E,CD,CE,R,RP,RE] 
cdef np.ndarray[double,ndim=1] y0 = np.array([0.,0.,0.,0.,0.4,0.,0.25]) 
cdef np.ndarray[double,ndim=2] E_simulated = np.zeros([10000,5000]) 
cdef np.ndarray[double,ndim=2] r = np.zeros([10000,5000]) 
cdef np.ndarray[double,ndim=1] E_avg = np.zeros([10000]) 
cdef np.ndarray[double,ndim=1] k = np.zeros([19]) 
                              ^ 
------------------------------------------------------------ 
 
myc_rb_e2f_pyx.pyx:56:31: Buffer types only allowed as function local variables 
 
Error compiling Cython file: 
------------------------------------------------------------ 
... 
cdef np.ndarray[double,ndim=1] y0 = np.array([0.,0.,0.,0.,0.4,0.,0.25]) 
cdef np.ndarray[double,ndim=2] E_simulated = np.zeros([10000,5000]) 
cdef np.ndarray[double,ndim=2] r = np.zeros([10000,5000]) 
cdef np.ndarray[double,ndim=1] E_avg = np.zeros([10000]) 
cdef np.ndarray[double,ndim=1] k = np.zeros([19]) 
cdef np.ndarray[double,ndim=1] d = np.zeros([7]) 
                              ^ 
------------------------------------------------------------ 
 
myc_rb_e2f_pyx.pyx:57:31: Buffer types only allowed as function local variables 
 
Error compiling Cython file: 
------------------------------------------------------------ 
... 
cimport numpy as np 
^ 
------------------------------------------------------------ 
 
myc_rb_e2f_pyx.pyx:1:0: Buffer vars not allowed in module scope 
An exception has occurred, use %tb to see the full traceback. 
 
SystemExit: error: command 'gcc' failed with exit status 1 

任何人都可以帮助我解决我在声明数组时出错的地方吗?

请您参考如下方法:

错误信息很清楚:缓冲区类型的变量在顶层是不允许的。将所有从 t 的声明开始的代码放在一个函数中,比如说 main,然后调用它。