Python PyArray_大小的正确用法是什么?
我不熟悉C语言中的numpy数组。下面是一段代码,让我1)将一组1-D、64位浮点numpy数组传递给C语言,2)遍历每个数组,打印其内容Python PyArray_大小的正确用法是什么?,python,c,numpy,Python,C,Numpy,我不熟悉C语言中的numpy数组。下面是一段代码,让我1)将一组1-D、64位浮点numpy数组传递给C语言,2)遍历每个数组,打印其内容 #include <stdio.h> #include <stdlib.h> #include <stddef.h> #include "Python.h" #include "numpy/arrayobject.h" #include "list_of_ndarrays_lib.h" void print_all(Py
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include "Python.h"
#include "numpy/arrayobject.h"
#include "list_of_ndarrays_lib.h"
void print_all(PyObject *list) {
int i, j;
PyArrayObject *arrayObj;
double *arrayData;
for (i = 0; i < PyObject_Length(list); i++) {
arrayObj = (PyArrayObject *) PyList_GET_ITEM(list, i);
arrayData = PyArray_DATA(arrayObj);
for (j = 0; j < PyArray_SHAPE(arrayObj)[0]; j++) {
printf("%f ", arrayData[j]);
}
printf("\n");
}
}
#包括
#包括
#包括
#包括“Python.h”
#包括“numpy/arrayobject.h”
#包括“数组列表”
全部作废打印(PyObject*列表){
int i,j;
PyArrayObject*arrayObj;
双*阵列数据;
对于(i=0;i
这段代码可以工作,但是PyArray\u SHAPE(arrayObj)[0]
不能推广到n维数组,如果我将其替换为PyArray\u SIZE(arrayObj)
,则会出现分段错误
我用
PyArray\u SIZE
做了什么错误?我做了一些cython
编码,但没有做更基本的c
工作。但既然没有其他人回答,我就抛出一些想法
可能相关的文档部分是
另一个迭代数组的工具是nditer
。我熟悉它在python
和cython
中的用法。有一个很好的介绍页面
另一件事是查看numpy
源代码。我会去github存储库,搜索这个变量
您对SHAPE的迭代相当于:
for i in range(arr.shape[0]):
print arr[i]
您的arrayData[j]
正在使用与Python版本相同的数组索引代码
2d等价物(在Python中)是:
我怀疑c等价物也有类似的结构
for i in range (arr.size):
print arr[i]
获取索引器:索引3超出大小为3的轴0的界限。我假设在没有边界检查的情况下,会出现分段错误
我怀疑使用SIZE
时,您需要直接通过DATA
bufer,而不是使用某种形式的arrayData[j]
。换句话说,获取缓冲区指针,并按itemsize
SIZE
次数步进该指针
nditer
将为您节省大量的详细工作
A在numpy/core计算中有几个地方。c我看到一个类似以下的块:
n = PyArray_SIZE(ap)/m;
rptr = (npy_intp *)PyArray_DATA(rp);
for (ip = PyArray_DATA(ap), i = 0; i < n; i++, ip += elsize*m) {
arg_func(ip, m, rptr, ap);
rptr += 1;
}
n=PyArray\u大小(ap)/m;
rptr=(npy_intp*)PyArray_数据(rp);
对于(ip=PyArray_DATA(ap),i=0;i
如果m=1
,则应逐元素(每个elsize
字节长)将ip
指针步进数据缓冲区,并将其传递给arg_func
,以执行操作。通常使用PyArray\u SIZE
检查数组是否为空(=0)
另一种选择是使用
PyArray\u flatte
(或者更好的PyArray\u Ravel
)来展平数组,然后使用形状
迭代。我认为这里的问题可能是所有Py*功能,包括PyArray*功能,除非您正确地修改代码,使其成为C扩展模块,否则风险自负
关于这个问题的清晰文字是很重要的。有一点样板,但除此之外,这个方法非常好。没有外部依赖项(如Boost.Python),它使您的Python代码非常干净,无需通过ctypes指定函数签名。只需添加
import_array()代码>在print_all()开头调用。它将初始化数组函数C-API。那么您是否正在尝试打印展开的arrayData
的所有元素?或者n维形状应该影响打印布局吗?是的,只打印展平版本的所有元素。(我只是使用print作为一种通用操作,它迭代所有元素,因为这是说明问题的最简单的示例。)numpy数组的大小是shape元素的乘积。。。你可以手动计算。谢谢你提供的信息。查看numpy C源代码是一个好主意;行。小提示:我担心使用他们的迭代器,因为它似乎对任何对象都是通用的,而在连续数组中循环没有相关的开销。这可能只是我的直觉不好。也许他们以一种聪明的方式编写了迭代器。我有点惊讶,我发现在迭代中使用大小的例子太少了。将数据缓冲区作为C数组处理速度很快,但有限。(nd)迭代器使您可以作为numpy对象访问数组元素,而无需进一步的索引开销。如果您以协调的方式(例如z[i]=x[i]*y[i])在多个数组上迭代,这也很好。该链接现在是垃圾邮件。我刚刚验证了它,并用它的存档版本替换了它
n = PyArray_SIZE(ap)/m;
rptr = (npy_intp *)PyArray_DATA(rp);
for (ip = PyArray_DATA(ap), i = 0; i < n; i++, ip += elsize*m) {
arg_func(ip, m, rptr, ap);
rptr += 1;
}