我需要使用各种大小的2D numpy数组执行大量工作,我想将这些计算卸载到cython上.我的想法是我的2D numpy数组将从python传递到cython,在那里它将转换为c-array或内存视图,并用于其他c级函数的级联中进行计算.
经过一些分析后,由于一些严重的python开销,我排除了在cython中使用numpy数组.使用内存视图更快,更容易使用,但我怀疑我可以使用c-arrays进一步加速.
这是我的问题 - 我怎样才能在cython中声明一个2D c-array而不用设定值预定义它的尺寸?例如,我可以通过这种方式从numpy创建一个c-array:
narr = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]], dtype=np.dtype("i"))
cdef int c_arr[3][4]:
for i in range(3):
for j in range(4):
c_arr[i][j] = narr[i][j]
Run Code Online (Sandbox Code Playgroud)
然后将其传递给函数:
cdef void somefunction(int c_Arr[3][4]):
...
Run Code Online (Sandbox Code Playgroud)
但这意味着我有一个固定的数组sizde,在我的情况下将是无用的.所以我尝试过这样的事情:
narr = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]], dtype=np.dtype("i"))
cdef int a = np.shape(narr)[0]
cdef int b = np.shape(narr)[1]
cdef int c_arr[a][b]: # INCORRECT - EXAMPLE ONLY
for i in range(a):
for j in range(b):
c_arr[i][j] = narr[i][j]
Run Code Online (Sandbox Code Playgroud)
打算将它传递给这样的函数:
cdef void somefunction(int a, int b, int c_Arr[a][b]):
...
Run Code Online (Sandbox Code Playgroud)
但它不起作用,编译失败,错误"不允许在常量表达式中".我怀疑我需要以某种方式使用malloc/free吗?我看了一下这个问题(如何在Cython中声明2D列表),但它没有提供我的问题的答案.
我尝试将一个复杂的函数形式 Python 重写为 Cython 以大大加快它的速度,但遇到以下问题:在编译我的函数 hh_vers_vector.pyx 时使用
setup(
ext_modules=cythonize("hh_vers_vector.pyx"),
)
Run Code Online (Sandbox Code Playgroud)
它引发以下错误
cdef int numSamples = len(Iext);
# initial values
cdef float v[numSamples]
^
------------------------------------------------------------
hh_vers_vector.pyx:47:27: Not allowed in a constant expression
Run Code Online (Sandbox Code Playgroud)
但是,如果我将“numSamples”作为数字输入函数,则没有问题。我不明白,因为我认为 len(Iext) 也会返回一个数字 10.000 。那么为什么 Cython 对这个表达式有问题呢?
cdef float v[numSamples] # ERROR
cdef float v[10000] # NO ERROR
Run Code Online (Sandbox Code Playgroud)
到目前为止,我的函数看起来像这样:
from math import exp
import time
def hhModel(*params, Iext, float dt, int Vref):
## Unwrap params argument: these variables are going to be optimized
cdef float ENa = params[0]
cdef …
Run Code Online (Sandbox Code Playgroud)