PyArray_New或PyArray_SimpleNewFromData指定3D数组的尺寸

时间:2017-01-20 12:21:28

标签: python c++ c numpy

我有1维浮点数组(来自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部分相同。

我的问题是这个1维数组实际上应该是3维ndarray。我可以控制我的result浮点数组的构造方式,如果可能的话,我希望将连续的内存块解释为3维数组。

我认为这可以通过指定shape变量来完成,但是,我无法找到有关内存将如何解释的任何参考。

说我需要我的数组看起来像:np.empty((x,y,z))。当我在shape变量中指定时,result数组的哪个部分构成第一个维度,第二个维度的哪个部分依此类推?

2 个答案:

答案 0 :(得分:1)

您可以使用pybind11。您实际上可以将自己置于单takes a c arrayreads from it作为一个整体视图的单元测试中

答案 1 :(得分:1)

有描述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}

data标识实际存储值的数据缓冲区的位置。在您的构造中,这将是您的C数组(或副本)。

在这种情况下,它是一个96字节的缓冲区 - 每个元素4个字节。此缓冲区由arange函数创建,并由reshape“重用”。

In [229]: arr.tostring()
Out[229]: b'\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\t\x00\x00\x00\n\x00\x00\x00\x0b\x00\x00\x00\x0c\x00\x00\x00\r\x00\x00\x00\x0e\x00\x00\x00\x0f\x00\x00\x00\x10\x00\x00\x00\x11\x00\x00\x00\x12\x00\x00\x00\x13\x00\x00\x00\x14\x00\x00\x00\x15\x00\x00\x00\x16\x00\x00\x00\x17\x00\x00\x00'

In [230]: len(_)
Out[230]: 96
In [231]: 24*4

descrarr.dtype标识字节的解释方式 - 此处为4字节整数,'

shapestrides确定如何查看1d数组 - 在本例中为3d数组。

In [232]: arr.strides
Out[232]: (48, 16, 4)
In [233]: arr.shape
Out[233]: (2, 3, 4)

这表示第一维(平面)长48个字节,其中有2个。第2行(每行)长16个字节,列元素之间的步长为4个字节。

通过简单地改变步幅和形状,可以将1d阵列视为2d,3d。甚至通过更改shapestrides(以及另一个属性order)来实现数组转置。