cython中的二维数组切片

时间:2017-10-04 13:25:51

标签: python arrays numpy cython

我有一个简单的问题,为什么效率不高:

import numpy as np
cimport numpy as c_np

import cython
def function():
  cdef c_np.ndarray[double, ndim=2] A = np.random.random((10,10))
  cdef c_np.ndarray[double, ndim=1] slice

  slice = A[1,:]  #this line is marked as slow by the profiler cython -a
  return

如何在没有开销的情况下在python中切割numpy矩阵。 在我的代码中,A是一个邻接矩阵,因此切片是我的路由算法中的邻居。

2 个答案:

答案 0 :(得分:2)

注释器标记的行只是建议,不是基于实际的分析。我认为它使用了一个相对简单的启发式方法,比如python api调用的数量。它也没有考虑调用某些东西的次数 - 紧密循环中的黄线比一次调用的东西重要得多。

在这种情况下,你正在做的是相当有效的 - 一次调用numpy来获取切片数组,以及将该数组赋值给缓冲区。

生成的C代码看起来可能更好使用功能相同的memoryview语法,但您必须进行分析以确定这实际上是否更快。

%%cython -a
import numpy as np
cimport numpy as c_np

import cython
def function():
  cdef double[:, :] A = np.random.random((10,10))
  cdef double[:] slice

  slice = A[1,:]
  return

答案 1 :(得分:1)

冒着重复已经很好的答案(而不是回答问题!)的风险,我将指出与注释器的常见误解......黄色表示很多与python解释器的交互。那个(以及扩展后看到的代码)在优化时是一个非常有用的提示。

然而!引用有关代码优化的每篇文档的第一段:

  

首先配置文件,然后进行优化。说真的:不要猜测,首先介绍一下。

注释绝对不是个人资料。查看关于性能分析的cython文档,以及线性分析How to profile cython functions line-by-line

的答案

作为一个例子,我的代码有一些亮黄色,它在大数组上调用一些numpy函数。实际上非常非常小的空间需要改进*因为python交互开销在这些大数组上进行了大量的计算。

*我或许可以通过直接使用numpy C接口来解决一些问题,但是再次通过大量计算进行摊销。