Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在Cython中声明2D列表_Python_Cython - Fatal编程技术网

Python 如何在Cython中声明2D列表

Python 如何在Cython中声明2D列表,python,cython,Python,Cython,我试图编译这种代码: def my_func(double c, int m): cdef double f[m][m] f = [[c for x in range(m)] for y in range(m)] ... 其中提出: Error compiling Cython file: ------------------------------------------------------------ def grow(double alpha, double

我试图编译这种代码:

def my_func(double c, int m):
    cdef double f[m][m]

    f = [[c for x in range(m)] for y in range(m)]
    ...
其中提出:

Error compiling Cython file:
------------------------------------------------------------
def grow(double alpha, double beta, double gamma, int m, int s):
    cdef double f[m][m]
                     ^
------------------------------------------------------------
test.pyx:6:22: Not allowed in a constant expression
在此之后,我假设无法在指定位置使用变量,并尝试使用数值:

def my_func(double c, int m):
    cdef double f[500][500]

    f = [[c for x in range(500)] for y in range(500)]
    ...
但我得到:

Error compiling Cython file:
------------------------------------------------------------
    f = [[beta for x in range(500)] for y in range(500)]
     ^
------------------------------------------------------------
test.pyx:13:6: Assignment to non-lvalue 'f'
所以,我想知道如何在cython代码中声明和制作2D列表。我在谷歌搜索“Cython2D列表”的文档中找不到这种例子

这是一个由500个双精度C数组组成的C数组。这是500*500压缩双精度值(在本例中存储在堆栈上,除非Cython做了一些奇怪的事情),没有任何间接寻址,这有助于提高性能和缓存利用率,但显然增加了严格的限制。也许你想要这个,但是你应该先学习足够多的C来知道这意味着什么。顺便说一下,一个限制是大小必须是编译时常量(取决于C版本;C99和C10允许),这就是第一条错误消息的内容

如果您确实使用数组,则不会像您那样初始化
f
,因为这没有任何意义
f
已经是500x500个双变量,不能将数组作为一个整体分配给它(后一条错误消息正试图告诉您这一点)。特别是,列表理解创建了一个完整的Python列表对象(您也可以从Cython使用,请参见下文),其中包含完整的“装箱”Python对象(
float
对象,在本例中)。列表与C数组不兼容。将嵌套的
for
循环与项目分配一起用于初始化。最后,这样一个数组需要500*500*8字节,这几乎是2个MiB。在某些系统上,这比整个堆栈都大,而在所有其他系统上,这是堆栈的很大一部分,这是一个坏主意。您应该堆分配该数组

如果您使用Python列表,请注意,性能和内存使用不会有太大的改进(假设您的代码将主要处理该列表),尽管您可能会从中获得一些便利。您可以不使用
cdef
,或者使用
list
作为类型(
object
也应该可以,但是您从中什么也得不到,所以您最好省略它)


NumPy阵列可能更快、内存效率更高、使用更方便。如果您可以在NumPy操作方面实现算法的性能关键部分,则完全不需要使用Cython就可以获得所需的加速比。

不要在Cython中使用列表理解。由于它们创建常规python列表,所以没有加速。Wiki,您应该在Cython中使用动态分配,如下所示:

from libc.stdlib cimport malloc, free

def my_func(double c, int m):
    cdef int x
    cdef int y
    cdef double *my_array = <double *>malloc(m * m * sizeof(double))

    try:

        for y in range(m):
            for x in range(m):
                #Row major array access
                my_array[ x + y * m ] = c

        #do some thing with my_array

    finally:
       free( my_array )
来自libc.stdlib cimport malloc,免费
定义我的函数(双c,整数m):
cdef int x
cdef int y
cdef double*my_数组=malloc(m*m*sizeof(double))
尝试:
对于范围内的y(m):
对于范围(m)内的x:
#行主阵列访问
my_数组[x+y*m]=c
#用我的_数组做点什么
最后:
免费(我的_数组)

但是,如果你需要一个2D数组的python对象,建议你使用它。

好吧,如果我不使用声明,我会得到编译过的代码,所以我猜我的声明是错误的。你真的想要一个列表列表,还是2D C数组?是的,它就像是编写的一样。我正在尝试加速非常慢的Python代码,这些代码在这个(以及另外两个)列表的每个元素上循环。想象一下这有多慢,这是一个非此即彼的问题。您声明了一个2d C数组,但使用Python列表来初始化
f
,因此我试图找出您是否混淆了这两个数组(或者,正如您的语言所示,您甚至没有意识到这两个数组之间的差异),或者您想要一个特定的数组,只是使用了错误的语法。是的,学习Cython:)在文档中,我看到了对象,在我看来是Python列表,声明为
p[1000]
,所以我认为应该这样声明列表。我应该尝试声明还是不需要声明列表?我在这里看到了一个例子:谢谢你的解释。我想我应该找一本C书作为参考,同样的建议也可以通过浏览Cython文档得到。所以,在我进一步了解C类型和操作之前,我只在本例中使用list。我认为C数组应该更有效,但它们不能从Cython函数返回到Python代码,而只能在Cython代码内部使用?目前,加速比仅为3倍,但我将尝试更进一步,首先是Numpy和Cython,因为如果相信的话,使用Numpy数组代替列表并不能提高此示例代码的性能。感谢您的代码片段,但当我看到
malloc
和类似术语时,我只是感到害怕。我还没有做到这一点,对我来说使用f2py更容易,但很长一段时间以来我一直想从Cython开始。正如我回答的,我现在将尝试使用Cython和Numpy数组,而不是Cython和Python列表。谢谢
from libc.stdlib cimport malloc, free

def my_func(double c, int m):
    cdef int x
    cdef int y
    cdef double *my_array = <double *>malloc(m * m * sizeof(double))

    try:

        for y in range(m):
            for x in range(m):
                #Row major array access
                my_array[ x + y * m ] = c

        #do some thing with my_array

    finally:
       free( my_array )