如何在C中访问numpy记录的内容?

eufgjt7s  于 2023-06-23  发布在  其他
关注(0)|答案(3)|浏览(111)

假设我创造了

descriptor = np.dtype([
        ('left', np.double, 3),
        ('center', np.double, 3),
        ('right', np.double, 3),
    ])
value = np.zeros(10, dtype=descriptor)

我可以验证value是作为90个double的连续内存实现的。
同样,我可以修改value[3],并看到更改反映在原始数组中。这意味着value[3]是某种数据结构,它指示了连续内存中的位置。
什么是value[3]?如果一个随机的value[i]被传递给一个C函数,C代码如何找到该元素引用的数据?对于普通的非记录子数组,您可以使用PyArray_DATA宏来获取数据的位置,即使该数据恰好位于某个更大的数组的中间。我还没有想出相应的东西来使用numpy记录。
创建的元素的mro()似乎是:

[numpy.record, numpy.void, numpy.flexible, numpy.generic, object]

问题更新。我不小心把变量名从value切换到了x
注意。我也想弄清楚我的问题是什么。value显然是一个数组,在numpy文档中很好地记录了如何访问它。value[3]是什么并不清楚。如果我把它传递给C代码,我如何找到包含它的数据的9个内存位置。

1l5u6lss

1l5u6lss1#

如果将value[3]传递给任何Python函数(包括用C实现的Python函数),则传递的不是value对象和内存偏移量,而是对单独的临时浮点值的引用。您可以像访问任何其他浮点值一样访问它。
如果你想从C访问numpy数组,我建议你看看Python C API文档中的缓冲区协议。
或者,也可以从C调用__getitem__方法。这一个将完全像从Python中一样工作,但它不是检索数组的大部分的最有效的方法。

gopyfrb3

gopyfrb32#

我想我找到答案了。numpy记录似乎满足array interface。在Python中,有关数组的信息可以通过查看record__array_interface__字段来获得。
在C代码中,我可以这样做:

PyObject* capsule = PyObject_GetAttrString(record, "__array_struct__");
    PyArrayInterface* interface = PyCapsule_GetPointer(result, NULL);
    // interface is in malloc'ed space that is freed by the capsule.
    ... interface->data gives the address of the data ...
    Py_XDECREF(capsule);
nhn9ugyo

nhn9ugyo3#

在SWIG中,要访问NumPy记录(结构化数组),例如您创建的记录,您可以使用SWIG生成的 Package 器代码与数据进行交互。以下是如何在SWIG中读取和访问NumPy记录的元素:
导入必要的SWIG模块:Python

import your_module_name

访问NumPy记录:Python

# Access the record at index 3
record = your_module_name.value[3]

访问记录的字段:python #访问'left'字段left_field = record['left']

# Access the 'center' field
center_field = record['center']

# Access the 'right' field
right_field = record['right']

对字段执行操作:python #修改'left'字段left_field[0] = 1.0 left_field 1 = 2.0 left_field[2] = 3.0
对left_field的更改将反映在原始NumPy记录中。
关于C代码如何找到记录元素引用的数据的问题,可以使用PyArray_DATA宏,正如您提到的。对于NumPy记录,您可以使用PyArray_DATA(record)访问底层数据位置,这将返回一个指向存储记录数据的内存块的指针。这允许您将record元素传递给C函数并访问其中的数据。
总之,您可以通过使用SWIG生成的 Package 器代码访问SWIG中的NumPy记录,然后使用它们各自的名称访问记录的字段。此外,在与C代码交互时,您可以使用PyArray_DATA宏来获取记录数据的内存位置。
来源:Backend Stack

相关问题