cython中的二维数组切片

Posted

技术标签:

【中文标题】cython中的二维数组切片【英文标题】:two dimensional array slicing in cython 【发布时间】:2017-10-04 13:25:51 【问题描述】:

我有一个简单的问题,为什么这样没有效率:

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 是一个邻接矩阵,因此切片是我的路由算法中的邻居。

【问题讨论】:

【参考方案1】:

注释器标记的行仅是建议,并非基于实际分析。我认为它使用了一个相对简单的启发式方法,比如 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

【讨论】:

我终于做到了,没有收获,html中的黄色少了=P。【参考方案2】:

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

但是! 引用每篇关于代码优化的文档的第一段:

先配置,再优化。说真的:不要猜测,先介绍一下。

而且注释绝对不是profile。查看有关 profiling 的 cython 文档,也许这个答案用于 line profiling How to profile cython functions line-by-line

作为一个例子,我的代码有一些亮黄色,它在大数组上调用一些 numpy 函数。实际上,改进的空间非常非常小*,因为 Python 交互开销已在那些大型数组上的大量计算中分摊。

*我可能可以通过直接使用 numpy C 接口来获得一点收益,但同样需要大量计算。

【讨论】:

以上是关于cython中的二维数组切片的主要内容,如果未能解决你的问题,请参考以下文章

在 D 中切片二维数组

在 Perl 中修改然后切片未知大小的二维数组

具有不同切片的二维 numpy 数组的平均值

c++ vector二维数组初始化与vector切片

c++ vector二维数组初始化与vector切片

Golang二维切片初始化