使用int的memoryview索引Cython memoryview

时间:2018-12-18 11:15:56

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

我使用Cython尝试做到这一点:

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

编译器抱怨:

  

指定的memoryview无效索引,键入int [:]

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

2 个答案:

答案 0 :(得分:2)

@ead自己展开循环的建议是一个很好的建议,但是我很想对基础的Numpy数组进行这种类型的索引编制,您可以使用memoryview的public String handleRequest() { DatePicker datePicker = new DatePicker(-1, -1); List<HubspotContact> contacts = MySoapClient.getRegistrants(datePicker.getStartDate(),datePicker.getEndDate()); insertToDB(contacts); return null; } 属性进行访问:

base

或者

array = array.base[sortIndices]

这具有快速编写代码的优点,并且只需要对工作array = np.asarray(array)[sortIndices] 代码进行最少的修改。它有一些小缺点:

  • 没有Cython加速,因为它基本上是Python对象调用-我希望这没关系,因为Numpy索引通常相当快,并且假设ndarray足够长,可以否定Python对象呼叫。

  • 如果基础对象实际上不是一个Numpy数组,则第一个版本会中断(因此,该函数在可以采用的类型上比在memoryview接口最初出现时要受到更多的约束。您可以使用来解决该问题第二个版本,应该创建一个Numpy数组,该数组包装在memoryview的内存周围。

答案 1 :(得分:0)

恐怕不可能像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,也不能被强制为{{1 }},因此无法由Cython进行处理。

我的第一个想法是,将功能添加到Cython的类型化内存视图并不难。但这可能不是那么容易以一致的方式完成的:操作的结果必须是新类型的内存视图(因为我们无法就地更改数组-生成的数组可能具有完全不同的尺寸)-但是哪种类型应该是基础缓冲区?在numpy世界中,这很容易,因为这里的所有内容都是numpy数组,但是类型化内存视图的基础缓冲区可以是numpy-array,Py_ssize_t,堆栈上的c-array等等。

您现在最好的选择可能是每手进行一次重新排序(以便您可以显式选择底层缓冲区的类型)并通过它替换损坏的代码,或者退回到该操作的numpy功能,如图所示。 @DavidWs的答案。