Python Cython numpy数组索引

Python Cython numpy数组索引,python,arrays,indexing,numpy,cython,Python,Arrays,Indexing,Numpy,Cython,我正在尝试使用cython加速一些python代码,并且我正在使用cython的-a选项来查看可以改进的地方。我的理解是,在生成的html文件中,突出显示的行是调用python函数的行,对吗 在下面的普通函数中,我使用缓冲区语法声明了numpy数组参数arr。我认为这允许索引操作完全在C中进行,而不必调用python函数。但是,cython-a(版本0.15)突出显示了我设置arr元素值的那一行,尽管不是我读取其中一个元素的那一行。为什么会发生这种情况?有没有更有效的方法访问numpy数组元素

我正在尝试使用cython加速一些python代码,并且我正在使用cython的
-a
选项来查看可以改进的地方。我的理解是,在生成的html文件中,突出显示的行是调用python函数的行,对吗

在下面的普通函数中,我使用缓冲区语法声明了numpy数组参数
arr
。我认为这允许索引操作完全在C中进行,而不必调用python函数。但是,
cython-a
(版本0.15)突出显示了我设置
arr
元素值的那一行,尽管不是我读取其中一个元素的那一行。为什么会发生这种情况?有没有更有效的方法访问numpy数组元素

import numpy
cimport numpy

def foo(numpy.ndarray[double, ndim=1] arr not None):
    cdef int i
    cdef double elem
    for i in xrange(10):
      elem = arr[i]          #not highlighted
      arr[i] = 1.0 + elem    #highlighted
编辑:另外,
模式
缓冲区参数如何与numpy交互?假设我没有更改
numpy.array
order
参数的默认值,那么使用
mode='c'
是否总是安全的?这实际上会对性能产生影响吗

在delnan的评论后编辑:
arr[i]+=1
也会突出显示(这就是为什么我首先将其拆分,以查看操作的哪个部分导致了问题)。如果我关闭边界检查以简化事情(这与突出显示的内容没有区别),则生成的c代码是:

  /* "ct.pyx":11
 *   cdef int i
 *   cdef double elem
 *   for i in xrange(10):             # <<<<<<<<<<<<<<
 *     elem = arr[i]
 *     arr[i] = 1.0 + elem
 */
  for (__pyx_t_1 = 0; __pyx_t_1 < 10; __pyx_t_1+=1) {
    __pyx_v_i = __pyx_t_1;

    /* "ct.pyx":12
 *   cdef double elem
 *   for i in xrange(10):
 *     elem = arr[i]             # <<<<<<<<<<<<<<
 *     arr[i] = 1.0 + elem
 */
    __pyx_t_2 = __pyx_v_i;
    __pyx_v_elem = (*__Pyx_BufPtrStrided1d(double *, __pyx_bstruct_arr.buf, __pyx_t_2, __pyx_bstride_0_arr));

    /* "ct.pyx":13
 *   for i in xrange(10):
 *     elem = arr[i]
 *     arr[i] = 1.0 + elem             # <<<<<<<<<<<<<<
 */
    __pyx_t_3 = __pyx_v_i;
    *__Pyx_BufPtrStrided1d(double *, __pyx_bstruct_arr.buf, __pyx_t_3, __pyx_bstride_0_arr) = (1.0 + __pyx_v_elem);
  }
/*“ct.pyx”:11
*cdef int i
*双元素

*对于xrange(10)中的i:#答案是荧光灯愚弄了读者。 我编译了您的代码,在突出显示下生成的指令是需要的 要处理错误情况和返回值,它们与数组赋值无关

事实上,如果您将代码更改为:

def foo(numpy.ndarray[double, ndim=1] arr not None):
    cdef int i
    cdef double elem
    for i in xrange(10):
      elem = arr[i]
      arr[i] = 1.0 + elem
    return # + add this
突出显示在作业的最后一行,而不是更多

您可以使用@cython.boundscheck进一步加快代码速度:

import numpy
cimport numpy
cimport cython

@cython.boundscheck(False)
def foo(numpy.ndarray[double, ndim=1] arr not None):
    cdef int i
    cdef double elem
    for i in xrange(10):
      elem = arr[i]
      arr[i] = 1.0 + elem
    return 

arr[i]+=1是否突出显示?另外,我相信您可以在由
cython-a
生成的HTML文档中查看为该特定行生成的代码,也许这有助于查看该行上发生的Python API调用。提供的C代码不显示绑定检查,也不显示环绕索引计算。所以我假设提问者在他的setup.py中禁用了它们。