【问题标题】:indexing Cython memoryview using memoryview of ints使用整数的 memoryview 索引 Cython memoryview
【发布时间】:2019-05-18 19:12:46
【问题描述】:

使用 Cython,我尝试这样做:

cpdef myFun(double[:] array):
    cdef int[:] sortIndices = np.argsort(array, kind='mergesort')
    array = array[sortIndices]

编译器报错:

指定的内存视图索引无效,键入 int[:]

如何使用某种整数数组索引此内存视图?是否只允许切片?我可以轻松地使用基于“数组”的索引和旧的 NumPy 数组缓冲区支持。 (我刚刚调整了我的代码以使用 memoryviews 来查看它是否会提高性能,但它实际上会中断......)

【问题讨论】:

    标签: python-3.x indexing cython typed-memory-views


    【解决方案1】:

    @ead 关于自己展开循环的建议是一个不错的建议,但是我很想对底层 Numpy 数组进行这种类型的索引,您可以使用 memoryview 的 base 属性访问它:

    array = array.base[sortIndices]
    

    或者

    array = np.asarray(array)[sortIndices]
    

    这具有快速编码的优点,并且只需要对您的工作 ndarray 代码进行最少的修改。它有一些小缺点:

    • 没有 Cython 加速,因为它基本上是一个 Python 对象调用 - 我希望这无关紧要,因为 Numpy 索引通常非常快,并且假设 sortIndices 的长度足以否定 Python 对象调用。

    • 如果底层对象实际上不是 Numpy 数组,则第一个版本会中断(因此,与最初出现的 memoryview 接口相比,该函数在它可以采用的类型方面受到更多限制。您可以通过使用来解决这个问题第二个版本,它应该创建一个包裹在 memoryview 内存周围的 Numpy 数组。

    【讨论】:

      【解决方案2】:

      恐怕不可能像 numpy 使用 int-arrays 那样使用类型化的内存视图作为索引。

      Cython 的文档states that

      内存视图使用 Python 切片语法的方式与 NumPy 类似。

      “相似”意味着它对于整数、切片 (:)、省略号 (...) 和 None(对应于 numpy.newaxis('None'))是相同的,但对于整数 不是-数组或布尔数组,可以在numpy中用作索引。

      负责生成对类型化内存视图的访问的 Cython 代码是 generate_buffer_slice_code,您需要知道的全部内容都在文档字符串中:

       """ 
       Slice a memoryviewslice. 
       indices     - list of index nodes. 
       If not a SliceNode, or NoneNode,  then it must be coercible to Py_ssize_t 
       ....
       """
      

      所以array 既不是 SliceNode(即:... 或例如0:33),也不是None,也不能强制转换为Py_ssize_t,因此不能由 Cython 处理.

      我的第一个想法是,将功能添加到 Cython 的类型化内存视图不会太难。但这可能并不容易以一致的方式完成:操作的结果必须是一个新的类型化内存视图(因为我们无法就地更改手头的数组 - 结果数组可能具有完全不同的维度) - 但是哪种类型应该是底层缓冲区?在 numpy-world 中更容易,所有东西都是 numpy 数组,但类型化内存视图的底层缓冲区可以是 numpy-array、array.array、堆栈上的 c-array 等等。

      您现在最好的选择可能是手动推出这种重新排序(这样您就可以明确选择底层缓冲区的类型)并通过它替换损坏的代码,或者为此操作回退到 numpy 功能,如@DavidWs 回答。

      【讨论】:

        猜你喜欢
        • 2019-06-21
        • 1970-01-01
        • 2016-09-07
        • 1970-01-01
        • 2012-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多