[英]Fastest way to get subset of numpy array in Cython
我有一个Cython函数,该函数接受一个2d整数的nd.array
(numpy数组),并返回一个1d numpy数组,其长度与输入的2d数组相同。
import numpy as np
cimport numpy as np
np.import_array()
cimport cython
def func(np.ndarray[np.float_t, dim=2] input_arr):
cdef np.ndarray[np.float_t, ndim=1] new_arr = ...
# do stuff
return new_arr
在程序的另一个循环中,我想调用func
,但是将其传递给从另一个2d数组动态创建的2d数组。 现在我有:
my_2d_numpy_array = np.array([[0.5, 0.1], [0.1, 10]]) # assume this is defined
cdef int N = 10000
cdef int k
for j in xrange(N)
# find some element k of interest
# create a 2d array on fly containing just the k-th to func()
func(np.array([my_2d_numpy_array[k]], dtype=float)) # KEY LINE
这行得通,但是我认为每次循环内对np.array
的调用np.array
产生巨大的开销,因为它可以追溯到Python。 由于func
仅读取数组并且不对其进行修改,因此如何仅将数组的视图作为指针传递给它,而不必回到Python来创建新数组呢? 我只想提取出my_2d_numpy_array
第k
行并将其传递给func()
更新 :一个相关的问题:如果我在循环中使用nd.array
但不需要func
中nd.array
的全部功能,我可以使func
代替静态C数组,并以某种方式处理nd.array
? 这样可以节省成本吗? 大概然后就不nd.array
对象传递给func
( nd.array
是一个对象)
您想使用Cython内存视图。 它们旨在在同一Cython模块的一部分函数之间传递数组切片。 您可能需要在Cython模块中内联该函数以获得全部性能优势,但这并不总是必要的。 您可以看一下文档 。 我最近为另一个问题写了一个相当冗长的答案,该问题探讨了何时应该使用内存视图。 如果您想更详细地研究切片为何能很好地与内存视图配合使用,请参阅此博客文章 。
如果不使用内存视图,则涉及NumPy数组的切片仍会涉及Python调用,并且不会在C语言中执行。
对于您的特定情况,这里有一些想法:如果要在Cython模块中的函数之间传递数组切片,则应该能够使用内存视图来传递切片。 这种方法的确依赖于编译时的优化,因此,如果需要在两个分别在不同时间编译的函数之间传递数组,则必须使用指针在函数之间传递数据。 这将意味着要进行一些仔细的指针算术运算,但是它仍然可以正常工作。 如果需要切片并使用NumPy函数,则可能最终不得不使用NumPy数组,但是尝试使用NumPy数组和查看相同数据的内存视图可能是值得的。 这样,您将能够将切片作为内存视图进行传递,而仅在真正需要它们时才需要创建NumPy数组。
另外,我建议将函数func
设为C函数,这样您在调用它时就不必承担调用Python函数的开销。 您可以使用cdef
或cpdef
关键字进行声明。 如果不需要从模块外部调用cdef
,请使用cdef
。 如果需要C函数和Python可访问的相应Python包装器,请使用cpdef
。
func(my_2d_numpy_array[k:k+1])
切片my_2d_numpy_array
而不是对其进行索引,即可获得所需形状的所需视图。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.