所以我在这里的线程中发现了类似的问题,但我还没有找到适合我的解决方案.

我正在用Python 3.9在Visual Studio 2022中构建Python的C扩展模块.该模块接受numpy数组作为输入并返回numpyarray.现在,我只需要让它读取输入数组的形状,并使用它来决定要创建的输出数组的大小.如果输入为shape(row,col),则输出为shape(2,row,col).

我动态分配一个包含2*row*col个元素的Carray.

以下是功能static PyObject* transform(PyObject* self, PyObject* args) {}的全部内容

import_array();
PyObject* data_obj;
PyArrayObject* data_array;


if (!PyArg_ParseTuple(args, "O", &data_obj)) {
    return NULL;
}

data_array = (PyArrayObject*)PyArray_FROM_OTF(data_obj, NPY_DOUBLE, NPY_ARRAY_IN_ARRAY);

if (data_array == NULL) {
    PyErr_SetString(PyExc_TypeError, "The data input must be a NumPy Array (2D or 3D)");
    return NULL;
}

int ndim = PyArray_NDIM(data_array);
npy_intp* data_shape = PyArray_SHAPE(data_array);

size_t rows, columns;
rows = data_shape[0];
columns = data_shape[1];

double* r_arr = (double*)malloc((rows * columns * 2) * sizeof(double));
if (r_arr == NULL) {
    PyErr_SetString(PyExc_ValueError, "Failed to allocate memory to arrays.");
    Py_DECREF(data_array);
}

然后,我在行和列上循环,并进行几次计算,在每行和列上生成两个数字,并将它们存储为r_arr[rr * rows + cc]r_arr[rr * rows + cc + rows * columns]

for (size_t cc = 0; cc < columns; ++cc) {
    // some calculation
    for (size_t rr = 0; rr < rows; ++rr) {
        // some calculation
        r_arr[rr * rows + cc] = result1;
        r_arr[rr * rows + cc + rows * columns] = result2;
        PySys_WriteStdout("%f, %f\n", r_arr[rr * rows + cc], r_arr[rr * rows + cc + rows * columns]);
    }
}

最后,我想把r_arr变成一个numpy数组,然后返回Python.我在这里try 了很多东西,但这是它的当前状态,基于阅读这里的其他线程.

npy_intp dims[3] = { 2, rows, columns };
PyObject* r_obj = (PyArrayObject *)PyArray_SimpleNewFromData(3, dims, NPY_DOUBLE, r_arr);

if (r_obj == NULL) {
    PyErr_Print("Failed to create internal arrays. Likely due to data input being incorrect shape.");
    return NULL;
}

Py_DECREF(data_array);
free(x);
free(y);
//free(r_arr);
PyArray_ENABLEFLAGS(r_obj, NPY_ARRAY_OWNDATA);
PySys_WriteStdout("Returning result\n");
return Py_BuildValue("O", r_obj);

在Python中,当我用shape(5,10)创建一个数组并将其用作输入时,我得到了以下结果.嵌套循环打印出正确的值,但返回的数组似乎是我使用np.empty((2, 5, 10))时所得到的结果.

我还try 使用PyArray_SimpleNewFromData()创建一个包含2*rows*columns个元素的1D numpy数组,这并没有什么不同.

输出:

0.023581, 4.986665
0.021305, 3.986672
0.018796, 2.986680
0.016282, 1.986689
0.014207, 0.986699
-0.986851, 4.986664
-0.986798, 3.986672
-0.986746, 2.986680
-0.986700, 1.986689
-0.986667, 0.986699
-1.986746, 4.986662
-1.986718, 3.986670
-1.986691, 2.986679
-1.986666, 1.986688
-1.986648, 0.986699
-2.986705, 4.986660
-2.986685, 3.986668
-2.986665, 2.986677
-2.986646, 1.986687
-2.986632, 0.986698
-3.986679, 4.986656
-3.986662, 3.986665
-3.986645, 2.986675
-3.986629, 1.986685
-3.986616, 0.986697
-4.986658, 4.986651
-4.986642, 3.986661
-4.986626, 2.986672
-4.986611, 1.986683
-4.986599, 0.986696
-5.986637, 4.986645
-5.986622, 3.986657
-5.986607, 2.986669
-5.986592, 1.986681
-5.986579, 0.986695
-6.986616, 4.986638
-6.986601, 3.986651
-6.986586, 2.986664
-6.986571, 1.986678
-6.986558, 0.986694
-7.986593, 4.986630
-7.986578, 3.986645
-7.986563, 2.986660
-7.986547, 1.986675
-7.986533, 0.986692
-8.986567, 4.986621
-8.986552, 3.986637
-8.986536, 2.986654
-8.986520, 1.986672
-8.986505, 0.986690
Returning result
array([[[ 1.14460020e-311,  1.14458244e-311,  1.14458542e-311,
          1.14478895e-311,  1.14478881e-311,  1.14478881e-311,
          1.14478893e-311,  1.14478894e-311,  1.14458542e-311,
          1.14478894e-311],
        [-8.98656729e+000,  1.14478893e-311,  1.14458542e-311,
          1.14478894e-311,  1.14478894e-311, -8.98655189e+000,
          1.14458542e-311,  1.14478895e-311,  1.14478895e-311,
          1.14478894e-311],
        [-8.98653594e+000,  1.14478884e-311,  1.14478894e-311,
          1.14478894e-311,  1.14478894e-311, -8.98652003e+000,
          1.14478884e-311,  1.14478894e-311,  1.14478894e-311,
          1.14478894e-311],
        [-8.98650487e+000,  1.14478893e-311,  1.14478895e-311,
          1.14478894e-311,  1.14478894e-311,  1.14478894e-311,
          1.14478884e-311,  1.14478894e-311,  1.14478894e-311,
          1.14478894e-311],
        [ 1.14478894e-311,  1.14478893e-311,  1.14478894e-311,
          1.14478894e-311,  1.14478894e-311,  1.14478894e-311,
          1.14478894e-311,  1.14478895e-311,  1.14478895e-311,
          1.14478895e-311]],

       [[ 1.14478894e-311,  1.14458542e-311,  1.14478895e-311,
          1.14478895e-311,  1.14478893e-311,  1.14478895e-311,
          1.14478893e-311,  1.14458542e-311,  1.14478884e-311,
          1.14478893e-311],
        [ 4.98662116e+000,  1.14478895e-311,  1.14478893e-311,
          1.14478894e-311,  1.14478895e-311,  3.98663750e+000,
          1.14478884e-311,  1.14458542e-311,  1.14478893e-311,
          1.14458542e-311],
        [ 2.98665407e+000,  1.14478895e-311,  1.14478895e-311,
          1.14478895e-311,  1.14478895e-311,  1.98667152e+000,
          1.14458542e-311,  1.14458542e-311,  1.14478895e-311,
          1.14478895e-311],
        [ 9.86690488e-001,  1.14478895e-311,  1.14478895e-311,
          1.14458542e-311,  1.14478884e-311,  1.14458542e-311,
          1.14478894e-311,  1.14478893e-311,  1.14458542e-311,
          1.14478895e-311],
        [ 1.14478895e-311,  1.14478884e-311,  1.14478893e-311,
          1.14478893e-311,  1.14458542e-311,  1.14478895e-311,
          9.38662745e-097,  2.07712408e-308,  1.14478658e-311,
          1.14458243e-311]]])

推荐答案

这是我的解决方案和一些其他修复.OP中的上述代码没有正确地从数组中获取数据(计算不依赖于元素的实际值,而只依赖于形状).它也不能正确计算指数.然而,解决方案的关键是我将数组实例化为PyArrayObjectPyArray_ZEROS(),然后从中获取数据进行操作.

PyArrayObject* data_array_obj;

if (!PyArg_ParseTuple(args, "O", &data_array_obj)) {
    return NULL;
}

if (data_array_obj == NULL) {
    PyErr_SetString(PyExc_TypeError, "The data input must be a NumPy Array");
    return NULL;
}

// Determine dimensionality and shape
int64_t ndim = PyArray_NDIM(data_array_obj);
size_t* data_shape = PyArray_SHAPE(data_array_obj);

if (ndim != 2) {
    PyErr_SetString(PyExc_TypeError, "The input NumPy Array must be 2D");
    return NULL;
}

size_t rows, columns;
rows = data_shape[0];
columns = data_shape[1];


// Get data from input array
double* data = PyArray_DATA(data_array_obj);

// Instantiate output array
npy_intp dims[3] = { 2, rows, columns };
PyArrayObject* r_obj_array = PyArray_ZEROS(3, dims, NPY_DOUBLE, 0);
double* r_data = PyArray_DATA(r_obj_array);


for (size_t cc = 0; cc < columns; ++cc) {
    // some calculation
    for (size_t rr = 0; rr < rows; ++rr) {
        // some calculation
        r_data[rr * columns + cc] = result1;
        r_data[rr * columns + cc + rows * columns] = result2;
    }
}

Py_DECREF(data_array);
return r_obj_array;

Python相关问答推荐

剧作家Python没有得到回应

将HLS纳入媒体包

如何使用scipy从频谱图中回归多个高斯峰?

2维数组9x9,不使用numpy.数组(MutableSequence的子类)

根据另一列中的nan重置值后重新加权Pandas列

如果值不存在,列表理解返回列表

如何列举Pandigital Prime Set

如何请求使用Python将文件下载到带有登录名的门户网站?

OR—Tools CP SAT条件约束

在Python argparse包中添加formatter_class MetavarTypeHelpFormatter时, - help不再工作""""

多指标不同顺序串联大Pandas 模型

启用/禁用shiny 的自动重新加载

找到相对于列表索引的当前最大值列表""

通过追加列表以极向聚合

如何按row_id/row_number过滤数据帧

语法错误:文档. evaluate:表达式不是合法表达式

如何在验证文本列表时使正则表达式无序?

以极轴表示的行数表达式?

为什么我的scipy.optimize.minimize(method=";newton-cg";)函数停留在局部最大值上?

为什么在更新Pandas 2.x中的列时,数据类型不会更改,而在Pandas 1.x中会更改?