在没有内存复制的情况下从 C 扩展对 Numpy 数组进行操作

Operate on Numpy array from C extension without memory copy

我是 C extensions 的 NumPy 新手,我想知道以下工作流程是否可行。

  1. 在 NumPy 中预分配一个数组
  2. 将此数组传递给 C 扩展
  3. 在 C 中就地修改数组数据
  4. 将 Python 中的更新数组与标准 NumPy 函数一起使用

特别是,我想在确保在任何步骤中使数据的新副本的同时做到这一点。

我熟悉 C 端的样板文件,例如 PyModuleDefPyMethodDefPyObject* 参数,但我看到的很多示例都涉及对 C 的强制转换据我了解涉及复制 and/or 转换的数组。我也知道 Cython,尽管我不知道它是否在幕后进行类似的强制转换或复制。我对 ndarray 上带有数字(例如 int32)值的简单索引 get- 和 set- 操作特别感兴趣。

有人可以提供一个创建 NumPy 数组、在 C 扩展中就地修改它并随后在 Python 中使用结果的最小工作示例吗?

Cython 不会创建 numpy 数组的新副本,除非您特别要求它使用 numpy 函数这样做,因此它在处理 numpy 数组时尽可能高效,请参阅 Working with NumPy

在编写原始 C 模块和使用 cython 之间进行选择取决于编写模块的目的。 如果您正在编写一个仅供 python 使用的模块,以尽可能快地使用 numpy 数组执行非常小的特定任务,那么一定要使用 cython,因为它也会自动正确注册模块处理内存并防止人们在编写 C 代码时犯下的常见错误(如内存管理问题),以及自动化编译器包含并允许整体上更容易访问复杂的功能(如使用 numpy 迭代器)。

然而,如果您的模块将在其他语言中使用并且必须 运行 独立于 python 并且必须与 python 一起使用而没有任何开销,并且实现一些复杂的 C 数据结构并需要大量 C 功能,然后一定要创建自己的 C 扩展(甚至是 dll),并且您可以将指针从 python 传递到 numpy 数组(使用 numpy.ctypeslib.as_ctypes_type), or pass the python object itself and return it (but you must make a .pyd/so instead of dll), or even create numpy array on C side and have it managed by python (but you will have to understand the numpy C API) .