微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 c 扩展中使用 python ndarray?

如何解决如何在 c 扩展中使用 python ndarray?

我正在尝试将 c 扩展名与基于 python 的代码一起使用。我正在将一些用 java 编写的代码导入到 python,但是当我运行 python 代码时,它需要永远完成它的工作。 (在java中花费了~3sec,但在python中花费了~2h。原始代码非常粗糙并且有很多循环,但是消除或合并这些循环有点困难)。所以我想用 c++ 编写我的代码的一部分并将它导入到 python 代码中使用。 我不擅长python和c++,所以我希望我的问题不要太愚蠢。

环境:Windows 10 64 位,python 3.7.6 32 位,visual studio 2019

我应该将 ndarrays 传递给 c 扩展,在那里做一些工作来改变这个数组的值,并且应该将这个数组分配给具有更改值的原始 python ndarray

于是尝试制作c扩展代码生成*.pyd并在python代码调用。但是,它只是在某个时刻完成,没有任何错误或警告消息。在这里,我附上了我的代码的一部分,并指出了代码突然结束的地方。至少在问题发生时我有足够的内存。

(好吧,我不需要将 float 转换为 double。但我不知道如何将 ndarray 转换为 float 数组,所以我只是使用了 PyFloat_AsDouble。)

#include <algorithm>
#include <iostream>
#include <Python.h>
#include <ndarraytypes.h>
 
int some_func(args)
{
... // Here I do some job and change the values in b_doubles array. It takes long time so I want to do this job in c++
}
 
static PyObject* c_func(PyObject* self,PyObject* args)
{
 PyObject* a; // 512 x 512 ndarray passed from python
 PyObject* b; // 3 x 60 ndarray passed from python
 PyObject* key;
 double* a_doubles; // want to translate ndarray a to an array that c++ can understand
 double* b_doubles; // want to translate ndarray b to an array that c++ can understand
 PyObject* item_a = NULL;
 PyObject* item_b = NULL;
 
 if (!PyArgs_ParseTuple(args,"OO",&a,&b)
 {
  return NULL;
 }
  
 int lena = PyObject_Size(a);
 int lenb = PyObject_Size(b);
 a_doubles = (double *)malloc(sizeof(double) * lena);
 b_doubles = (double *)malloc(sizeof(double) * lenb);
 
 for (int i=0; i<lena; i++) 
 {
  key = Py_BuildValue("i",i);
  item_a = PyObject_GetItem(a,key); // ★ Here or
  a_doubles[i] = PyFloat_AsDouble(item_a); // ★ here the code just finished suddenly and silently.
  // Here,lena has correct value,'a' also is correct array with correct values.
 } 
 
 for (int i=0; i<lenb; i++)
 {
  key = Py_BuildValue("i",i);
  item_b = PyObject_GetItem(b,key);  // Probably I have same problem here
  b_doubles[i] = PyFloat_AsDouble(item_b);  // or in this point.
 }
 
 int something = some_func(a_doubles,b_doubles); // I need to return both int return (something) and b_doubles to python code.
 
 PyObject* b_return = PyTuple_New(lenb);
 for (int i=0; i<lenb; i++)
 {
  key = Py_BuildValue("i",i);
  PyTuple_SetItem(b_return,i,PyFloat_FromDouble(b[i]));
 }
 
 free(a_doubles);
 free(b_doubles);
 return Py_BuildValue("iO",something,b_return);
}
 
 
static PyMethodDef myMethod[] ={
...
};
 
static struct PyModuleDef myModule = {
...
};
 
PyMODINIT_FUNC PyInit_myModule(void)
{
 return PyModule_Create(&myModule);
}

如果您有任何想法或更多信息,请告诉我。 先感谢您。 :)

最好的祝福, 耶苏

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。