PyArray_New或PyArray_SimpleNewFromData指定三维阵列的尺寸

PyArray_New or PyArray_SimpleNewFromData specify dimensions for a 3D array

本文关键字:PyArray 阵列 三维 New SimpleNewFromData      更新时间:2023-10-16

我有一个一维浮点数组(来自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形状。如果"整形"没有意义,您需要复习一些数组基础知识,包括viewcopy的概念。

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。甚至阵列转置也是通过改变shapestrides(以及另一个属性order)来实现的。

您可以使用pybind11来实现这一点。实际上,您可以将自己建立在一个单元测试的基础上,该测试获取一个c数组,并将其作为numpy视图进行读取