Python Numpy数组切片转换内部数据
我正在编写一个C扩展,它将处理numpy数组。我已经编写了一个函数来读取和输出numpy数组。使用它,我注意到在输入数组中使用切片时出现的一种奇怪行为 读取(boolan)数组的C函数: 打印是通过以下方式完成的:Python Numpy数组切片转换内部数据,python,c,arrays,numpy,slice,Python,C,Arrays,Numpy,Slice,我正在编写一个C扩展,它将处理numpy数组。我已经编写了一个函数来读取和输出numpy数组。使用它,我注意到在输入数组中使用切片时出现的一种奇怪行为 读取(boolan)数组的C函数: 打印是通过以下方式完成的: void printArrChar(char **arr, int dim1, int dim2) { int i, j; for (i = 0; i < dim1; i++) { for (j = 0; j < dim2; j++) {
void printArrChar(char **arr, int dim1, int dim2) {
int i, j;
for (i = 0; i < dim1; i++) {
for (j = 0; j < dim2; j++) {
printf("%i ", arr[i][j]);
}
printf("\n");
}
}
输出为:
a:
[[0 1 0 0 0 0]
[0 0 0 1 0 1]
[0 1 0 1 0 1]
[0 0 1 1 0 1]
[1 1 0 0 0 1]
[0 0 1 1 1 0]
[1 1 0 1 1 1]
[0 1 0 0 1 0]
[0 0 0 1 0 0]
[0 0 1 0 1 1]]
aSlicing:
[[0 1 0 0 0 0]
[0 0 0 1 0 1]
[0 1 0 1 0 1]
[0 0 1 1 0 1]
[1 1 0 0 0 1]
[0 0 1 1 1 0]
[1 1 0 1 1 1]
[0 1 0 0 1 0]
[0 0 0 1 0 0]
[0 0 1 0 1 1]]
C output for a:
0 1 0 0 0 0
0 0 0 1 0 1
0 1 0 1 0 1
0 0 1 1 0 1
1 1 0 0 0 1
0 0 1 1 1 0
1 1 0 1 1 1
0 1 0 0 1 0
0 0 0 1 0 0
0 0 1 0 1 1
C output for aSlicing:
0 0 0 0 1 0
1 0 0 0 1 0
1 0 1 0 1 1
0 0 0 0 0 1
0 1 0 0 0 1
0 1 1 1 0 1
1 0 1 0 0 0
0 0 0 1 1 1
0 1 0 1 1 1
1 0 1 0 0 1
很容易看出,a
和aSlicing
是python的相同数组。但是,在中读取数据的C函数将数据视为某种转置。C视为被许可,就好像它是
a.T.reshape((10,6))
有人知道为什么会出现这个错误,以及如何正确地规避它吗?当然,在C代码中转置是很容易的。但是,我希望我的程序能够处理这两种类型的数组
我更喜欢C扩展中的解决方案,即扩展的用户不必关心他们的输入是否被“切片”。尽管如此,我还是尝试将aSliced
的一个深度副本放入扩展中,这与aSliced
的错误结果相同
我正在使用python 3.4 64位、numpy 1.9.1、Win8 64位和Visual Studio 10 64位C编译器。正如hpaulj所指出的,可以使用标志
F_continuous
来计算内存结构。我花了很多时间试图找到从C中读取此标志的方法。据我所知,可以通过计算trials\u array->flags%2
的值来完成。然而,我没有找到任何关于这个问题的明确解释的参考资料
trials\u array->flags
是一个整数。numpy标志常量NPY\u C\u continuous
,NPY\u F\u continuous
等是两个幂的整数。如果trials\u array->flags
的二进制表示中的相应位置为1,则设置该标志似乎是正确的
即使知道了内存结构,也不像我想象的那样读取数组。我找到了一种更简单的方法将numpy数组转换为C数组:使用
char *myArray;
PyArrayObject *myArray_Numpy;
PyArray_AsCArray(&myArray_Numpy, (void *) &myArray, myArray_Numpy->dimensions, 2, PyArray_DescrFromType(NPY_BOOL));
//Do something with the array
PyArray_Free(myArray_Numpy, myArray);
我找到了一个使用这些函数的示例。请看
.flags
或数组接口。布尔索引生成一个副本,在本例中,它是F_连续的
!是否最好读取此标志,并根据结果使用不同的方式读取阵列内存?还是有其他更优雅的方式?我搜索了一段时间,但没有找到:如何从C中获取标志的值?数组标志上的文档:
a:
[[0 1 0 0 0 0]
[0 0 0 1 0 1]
[0 1 0 1 0 1]
[0 0 1 1 0 1]
[1 1 0 0 0 1]
[0 0 1 1 1 0]
[1 1 0 1 1 1]
[0 1 0 0 1 0]
[0 0 0 1 0 0]
[0 0 1 0 1 1]]
aSlicing:
[[0 1 0 0 0 0]
[0 0 0 1 0 1]
[0 1 0 1 0 1]
[0 0 1 1 0 1]
[1 1 0 0 0 1]
[0 0 1 1 1 0]
[1 1 0 1 1 1]
[0 1 0 0 1 0]
[0 0 0 1 0 0]
[0 0 1 0 1 1]]
C output for a:
0 1 0 0 0 0
0 0 0 1 0 1
0 1 0 1 0 1
0 0 1 1 0 1
1 1 0 0 0 1
0 0 1 1 1 0
1 1 0 1 1 1
0 1 0 0 1 0
0 0 0 1 0 0
0 0 1 0 1 1
C output for aSlicing:
0 0 0 0 1 0
1 0 0 0 1 0
1 0 1 0 1 1
0 0 0 0 0 1
0 1 0 0 0 1
0 1 1 1 0 1
1 0 1 0 0 0
0 0 0 1 1 1
0 1 0 1 1 1
1 0 1 0 0 1
a.T.reshape((10,6))
char *myArray;
PyArrayObject *myArray_Numpy;
PyArray_AsCArray(&myArray_Numpy, (void *) &myArray, myArray_Numpy->dimensions, 2, PyArray_DescrFromType(NPY_BOOL));
//Do something with the array
PyArray_Free(myArray_Numpy, myArray);