【问题标题】:What is the corresponding C-api name of the following numpy function in PythonPython中以下numpy函数对应的C-api名称是什么
【发布时间】:2022-10-04 19:22:09
【问题描述】:
  • 我想为 Python 编写一个 C 扩展库,旨在用 C 替换 Python 代码。
  • 和 Python 代码有如下几行:
import numpy as np
a = np.array([1,3,12,0.43,234,-3,-4])
b = a[[1,3,5]]
print(b)

# array([ 3.  ,  0.43, -3.  ])

  • 与将 int 作为 numpy 数组的索引不同,此示例将数组视为索引。

  • 我很困惑获取给定 numpy 数组的指定索引,对应的 C-API 名称是什么?

  • NUMPY C-API 文件位于numpy c-api

  • 非常感谢。

【问题讨论】:

  • @MechanicPig:不,这是 numpy.ndarray.item 方法的 C API 版本。它不符合问题的要求。
  • PyObject_GetItem 会起作用,尽管使用 C API 与用 Python 编写相比不会有很大的好处。我认为没有可用于每个单独操作的直接 Numpy C API 函数
  • NUMPY C API 相当快,但它只包含我的 Python 代码的一小部分。为了加快速度,仍有大量纯 Python 代码需要用 C 重写。

标签: python arrays c numpy python-c-api


【解决方案1】:

高级 Numpy 函数并不意味着要从 C 中使用。事实上,并非所有这些函数都是用 C 实现的(有些是用纯 Python 实现的,调用其他本身用 C 实现的高级函数)。事实上,除了重用一些与可以直接在 C 中实现的代码相比效率不高的代码之外,这样做并没有太多好处。

Numpy 提供了一个非常简单的接口(您提供的那个),因此模块可以在 Numpy 数组上运行。在实践中,低级 C 模块通常使用PyArray_GetPtr(或更具体的宏,如PyArray_GETPTR2,同时检查标志以确保安全)提取指针,并基于步幅直接操作数组缓冲区(使用PyArray_STRIDES 提取)。 Numpy 数组只是一个具有固定大小和一些元信息的大原始缓冲区。视图添加了更多信息,例如维度数、形状、步幅等。如果可能,最好检查数组是否连续并为连续数组编写代码。实际上,当某些步幅设置为 1 时,编译器往往不会生成快速代码:您有责任在 C 中对此进行优化(这是 Numpy 在其函数中所做的,但这部分会引入一些开销)。经过优化以对连续数组进行操作的代码可以更快(主要是由于可能使用 SIMD 指令和更快的索引指令)。

虽然您可以使用PyArray_GETITEM,但由于可能的检查、低效的通用索引(破坏了许多编译器优化)以及编译器肯定不会内联函数,因此生成的代码将比直接访问慢得多。它可能比纯 Python 代码更快,但幅度不大(肯定类似于不使用直接索引的 Cython 代码)。

【讨论】:

  • 我发现我的问题中的 numpy 表达式等同于 numpy C func PyArray_Choose。你可以试试这个PyObject *PyArray_Choose(PyArrayObject *self, PyObject *op, PyArrayObject *ret, NPY_CLIPMODE clipmode) 并检查一下。谢谢您的回答
【解决方案2】:
  • 终于找到了这个numpy C func,它的名字是PyArray_Choose
  • 完整的func定义为PyObject *PyArray_Choose(PyArrayObject *self, PyObject *op, PyArrayObject *ret, NPY_CLIPMODE clipmode)
  • numpy choose

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-18
    • 2019-08-01
    • 1970-01-01
    • 2017-11-28
    • 2023-03-05
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多