我是在C中操作numpy数组的新手。下面是一段代码,它让我1)将一维,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(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");
}
}
此代码有效,但PyArray_SHAPE(arrayObj)[0]
并未对n维数组进行推广,如果我将其替换为PyArray_SIZE(arrayObj)
,则会出现分段错误。
PyArray_SIZE
我做错了什么?
答案 0 :(得分:2)
只需在print_all()开头添加$(document).ready(function() {
initMap();
});
调用即可。它将初始化数组函数C-API。
答案 1 :(得分:0)
我已完成一些cython
编码,但不是更基本的c
工作。但是,由于没有其他人回答,我会抛出一些想法。
迭代数组的另一个工具是nditer
。我熟悉它在python
和cython
中的用法。有一个很好的介绍页面。
http://docs.scipy.org/doc/numpy/reference/arrays.nditer.html#arrays-nditer http://docs.scipy.org/doc/numpy/reference/c-api.iterator.html
另一件事是查看numpy
源代码。我将转到github存储库,并对此变量进行搜索。
使用SHAPE进行的迭代等同于:
for i in range(arr.shape[0]):
print arr[i]
您的arrayData[j]
使用与Python版本相同的数组索引代码。
2d等价物(在Python中)是:
for i in range(arr.shape[0]):
for j in range(arr.shape[1]):
print arr[i,j]
我怀疑c等价物有类似的结构。
for i in range (arr.size):
print arr[i]
获得IndexError: index 3 is out of bounds for axis 0 with size 3
。我认为没有边界检查你会得到一个分段错误。
我怀疑SIZE
您需要直接通过DATA
缓存,而不是使用某种形式的arrayData[j]
。换句话说,获取缓冲区指针,并按itemsize
SIZE
次数执行。
nditer
将为您节省大量详细工作。
numpy / core calculation.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;
}
如果m=1
,这应该逐个ip
指针遍历数据缓冲区,逐个元素(每个elsize
个字节长),并将其传递给arg_func
以进行操作。更常见的是PyArray_SIZE
用于检查数组是否为空(== 0)。
另一个选择是使用PyArray_Flatten
(或更好PyArray_Ravel
)来展平数组,然后使用SHAPE
次迭代。
答案 2 :(得分:0)
我认为这里的问题可能是所有Py *功能,包括PyArray *功能,都是风险,除非你正确地修改你的代码成为C扩展模块。
关于这个主题的明确说明是here。有一些样板,但除此之外,这种方法非常好。没有外部依赖(如Boost.Python),它使您的Python代码非常干净,无需通过ctypes指定函数签名。