PyArray_New或PyArray_SimpleNewFromData指定三维阵列的尺寸
PyArray_New or PyArray_SimpleNewFromData specify dimensions for a 3D array
我有一个一维浮点数组(来自C空间),我想在python空间内读取它,但没有副本。到目前为止,我所做的(大部分阅读)是:
// wrap c++ array as numpy array
//From Max http://stackoverflow.com/questions/10701514/how-to-return-numpy-array-from-boostpython
boost::python::object exposeNDarray(float * result, long size) {
npy_intp shape[1] = { size }; // array size
PyObject* obj = PyArray_SimpleNewFromData(1, shape, NPY_FLOAT, result);
/*PyObject* obj = PyArray_New(&PyArray_Type, 1, shape, NPY_FLOAT, // data type
NULL, result, // data pointer
0, NPY_ARRAY_CARRAY_RO, // NPY_ARRAY_CARRAY_RO for readonly
NULL);*/
handle<> array( obj );
return object(array);
}
PyArray_New
注释部分在功能上等同于PyArray_SimpleNewFromData
注释部分。
我的问题是,这个一维数组实际上应该是一个三维ndarray。我可以控制我的result
浮点数组的构造方式,如果可能的话,我希望将连续的内存块解释为三维数组。
我认为这可以通过指定shape
变量来完成,但我找不到任何关于如何解释内存的参考。
假设我需要我的数组看起来像:np.empty((x,y,z))
。当我在shape
变量中指定时,result
数组的哪个部分将构成第一个维度,第二个维度的哪个部分,依此类推?
有一些文档描述了numpy数组的布局,例如。https://docs.scipy.org/doc/numpy/reference/arrays.html
但也许一个简单的例子会有所帮助。
让我们制作一个由24个整数组成的1d数组,并将其重塑为3d形状。如果"整形"没有意义,您需要复习一些数组基础知识,包括view
与copy
的概念。
In [226]: arr = np.arange(24).reshape(2,3,4)
In [227]: arr
Out[227]:
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
查看此数组的基本属性的一种方便方法是以下字典:
In [228]: arr.__array_interface__
Out[228]:
{'data': (159342384, False),
'descr': [('', '<i4')],
'shape': (2, 3, 4),
'strides': None,
'typestr': '<i4',
'version': 3}
CCD_ 10标识实际存储值的数据缓冲器的位置。在您的构造中,这将是您的C
数组(或副本)。
在这种情况下,它是一个96字节的缓冲区,每个元素4个字节。该缓冲区由arange
函数创建,并由reshape
"重用"。
In [229]: arr.tostring()
Out[229]: b'x00x00x00x00x01x00x00x00x02x00x00x00x03x00x00x00x04x00x00x00x05x00x00x00x06x00x00x00x07x00x00x00x08x00x00x00tx00x00x00nx00x00x00x0bx00x00x00x0cx00x00x00rx00x00x00x0ex00x00x00x0fx00x00x00x10x00x00x00x11x00x00x00x12x00x00x00x13x00x00x00x14x00x00x00x15x00x00x00x16x00x00x00x17x00x00x00'
In [230]: len(_)
Out[230]: 96
In [231]: 24*4
CCD_ 14或CCD_
CCD_ 16和CCD_。
In [232]: arr.strides
Out[232]: (48, 16, 4)
In [233]: arr.shape
Out[233]: (2, 3, 4)
这意味着第一个维度(平面)有48个字节长,其中有2个字节。第二个(每行)长16字节,列元素之间的步长为4字节。
通过简单地改变步幅和形状,可以将1d阵列视为2d、3d。甚至阵列转置也是通过改变shape
和strides
(以及另一个属性order
)来实现的。
您可以使用pybind11来实现这一点。实际上,您可以将自己建立在一个单元测试的基础上,该测试获取一个c数组,并将其作为numpy视图进行读取
- OpenMP阵列性能较差
- 如何将三维尺寸不固定的三维阵列展平为一维阵列
- 当我的阵列太大时出现分段错误
- 位阵列上的快速AND运算
- 阵列必须使用大括号封闭的初始器进行初始化
- 没有从阵列<float>到阵列<int>的可行转换
- C++动态安全 2D 交错阵列
- 将平面阵列重塑为复杂的特征类型
- 如何使用英特尔 PIN 捕获阵列的所有负载?
- 为什么我能够为阵列分配比计算机实际拥有的内存更多的内存
- 库特<<恩德尔;不适用于打印 2D 阵列
- 数组类 阵列的打印输出
- 从较小的阵列到较大的阵列的元素级转换
- 仅在大型阵列上出现合并排序分段错误
- 从阵列C++中删除重复项
- 阵列的大小在C++中是否灵活?
- 反转阵列中的正序列
- 具有可变尺寸的 C++ 2D 阵列
- 二维阵列的动态分配
- 重新增长阵列时出错:写入时缓冲区溢出