python - 使用 C API 创建自定义类对象的 numpy 数组

标签 python numpy python-c-api python-c-extension

我想使用 C API 创建一个包含 Quaternion 类型对象的 numpy 数组,这是我用 C++ 编写的类。我已经有了一个数组(实际上是一个 std::vector),我想制作一个副本——或者如果可能的话使用相同的内存。

因为这不是基本类型,我需要使用 Py_Object 类型,不能使用 PyArray_SimpleNew 或任何类似的简单类型。

我猜我可能想使用 PyArray_NewFromDescr 甚至 PyArray_SimpleNewFromDescr,但我完全不知道如何创建 PyArray_Descr 对象我需要描述我的四元数类。

谁能给我一些关于如何制作 descr 对象的建议?或者让我更好地了解如何构建我的 numpy 数组?

这基本上是 this question 的更通用版本,没有干扰。

编辑:

使用 dastrobu 的提示和我的 SWIG 包装器,我找到了一种方法来做到这一点。我知道不是每个人都在使用 SWIG,但对于那些正在使用的人,my answer on my other question展示了我是如何解决的。

最佳答案

因为 Quaternion 不是直接的数字类型,你的数组必须有 numpy.object 作为 dtype。因此,您可以使用 PyArray_SimpleNew(..., NPY_OBJECT) 创建数组并填充数据。 问题是您的 Quaternion 类不是 python 类型。因此,用对类型 Quaternion 的对象的引用填充数组将不起作用。 (在这种情况下,如果你从 python 中填充了四元数的数组中提取一个元素,你会期望发生什么?) 相反,您需要用 PyQuaternion 之类的东西包装 Quaternion 类。包装器负责引用计数和内存管理。它看起来像:

typedef struct {
    PyObject_HEAD
    Quaternion *q;
}PyQuaternion;

static PyTypeObject PyQuaternion_Type = {
    PyObject_HEAD_INIT(NULL)
    0,                                        /*ob_size*/
    "Quaternion",                             /*tp_name*/
    sizeof(PyQuaternion),                     /*tp_basicsize*/
/* ... */
};


static PyObject *
PyQuaternion_new(PyTypeObject *type, PyObject *args, PyObject *kwds){
/* ... */
};

static int 
PyQuaternion_init(PyQuaternion *self, PyObject *args, PyObject *kwds){
/* ... */
};

static void PyQuaternion_dealloc(PyQuaternion *self){
/* ... */
};

此外,您可以为 PyQuaternionType 定义自己的 C-API,从而允许您从 Quaternions

创建 PyQuaternions
static PyObject *
PyQuaternion_New(Quaternion *q){
    PyQuaternion *self;
    self = (PyQuaternion *)PyQuaternion_Type.tp_new(type, NULL, NULL);
    self->q = q; 
    return (PyObject *)self;
}

请注意 self->q 将由 PyQuaternion_dealloc 函数处理,因此请考虑内存管理。最简单的方法是将所有权传递给包装器并让 PyQuaternion_dealloc 解除分配 self->q

PyQuaternion_New 函数允许您包装 Quaternion 对象并将它们填充到任何 python 容器中,例如列表、元组,当然还有带有 dtype 的 numpy 数组= numpy.object

关于python - 使用 C API 创建自定义类对象的 numpy 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19532871/

相关文章:

python - 命名一些使用 IronPython 和 Silverlight 编写的重要站点

python matplotlib 绘制稀疏矩阵模式

python - python中的时间格式

python - Flask - 获取 html 选择选项标签内的文本而不是选项的值

python - Numpy:对 NxM 数组的列(或行)的操作

python - 更正扩展模块中的循环垃圾收集

python - 将 Python 嵌入到 C 示例中不起作用

python - 如何在 Python3 中获取 PyObject 的字符串表示形式?

python - 更改原始对象时更改的对象列表

python - 如何判断 NumPy 是创建 View 还是副本?