python - 在 Cython 中获取 numpy 数组子集的最快方法

标签 python arrays numpy scipy 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,但向其传递一个从另一个二维数组动态创建的二维数组。现在我有:

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 都会产生巨大的开销,因为它会返回到 Python。由于 func 只读取数组而不修改它,我如何才能将数组的 View 作为指针传递给它,而不需要返回到 Python 来创建新数组?我只对取出 my_2d_numpy_array 的第 k 行并将其传递给 func()

更新:一个相关问题:如果我在循环内使用 nd.array 但不需要 nd.array< 的完整功能func 中,我可以让 func 改为采用静态 C 数组之类的东西,并以某种方式将 nd.array 视为那样吗?这样能节省成本吗?想必您不必将对象传递给 func (nd.array 是一个对象)

最佳答案

您想要使用 Cython 内存 View 。 它们设计用于在属于同一 Cython 模块的函数之间传递数组切片。 您可能需要在 Cython 模块中内联该函数才能获得完整的性能优势,但这并不总是必要的。 你可以看看documentation 。 我最近给另一个question写了一个相当长的答案。它会研究何时应该使用内存 View 。 如果您想更详细地了解为什么切片对内存 View 效果很好,请查看此 blog post .

如果您不使用内存 View ,涉及 NumPy 数组的切片仍然涉及 Python 调用,并且不会在 C 中执行。

针对您的具体情况,以下是一些想法: 如果您在 Cython 模块中的函数之间传递数组切片,您应该能够使用内存 View 来传递切片。 这种方法确实依赖于编译时优化,因此如果您需要在不同时间编译的两个函数之间传递数组,则必须使用指针在函数之间传递数据。 这意味着要进行一些仔细的指针算术,但它应该仍然有效。 如果您需要进行切片并使用 NumPy 函数,您可能最终不得不使用 NumPy 数组,但尝试使用 NumPy 数组和查看相同数据的内存 View 可能是值得的。 这样您就可以将切片作为内存 View 传递,而只需在真正需要时创建 NumPy 数组。

此外,我建议将函数 func 设为 C 函数,这样您在调用 Python 函数时就不必经历调用它的开销。 您可以使用 cdefcpdef 关键字来声明它。 如果不需要从模块外部调用它,请使用cdef。 如果您想要一个 C 函数和一个可供 Python 访问的相应 Python 包装器,请使用 cpdef。

关于python - 在 Cython 中获取 numpy 数组子集的最快方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21979504/

相关文章:

python - 如何降低二维numpy数组的稀疏程度?

python - Mayavi "Font Size"文本属性是否有效?

javascript - 带按钮 javascript 的 Python post 表单

php - 将两个数组合并或组合成单个数组

javascript - 订阅时Angular 2更改数组值

python - 在Python中计算两个二维数组之间的行相关系数

python - 如何在 64 位 Windows 上安装 SciPy?

python - 安装 shapefile/shapelib 未通过 conda 或 pip 找到

python - Pyramid - 上传图像并存储在磁盘上

php - 根据两个键值按 ASC 顺序对数组进行排序?