Python 将numpy数组传递并返回给C++;方法通过Cython

Python 将numpy数组传递并返回给C++;方法通过Cython,python,arrays,numpy,cython,Python,Arrays,Numpy,Cython,在这个网站上,关于在cython中使用numpy有很多问题,一个特别有用的问题是 但是,cython/numpy接口api,特别是确保内存连续数组的传递 在cython中编写包装函数的最佳方法是什么: 获取可能但不一定连续的numpy数组 调用C++类方法,签名为代码>双*DATAIIN,双* DATAOXOUT 返回方法写入的double*的numpy数组 我的尝试如下: cimport numpy as np import numpy as np # as suggested by

在这个网站上,关于在cython中使用numpy有很多问题,一个特别有用的问题是

但是,cython/numpy接口api,特别是确保内存连续数组的传递

在cython中编写包装函数的最佳方法是什么:

  • 获取可能但不一定连续的numpy数组
  • 调用C++类方法,签名为代码>双*DATAIIN,双* DATAOXOUT
  • 返回方法写入的
    double*
    的numpy数组
我的尝试如下:

cimport numpy as np
import numpy as np # as suggested by jorgeca

cdef extern from "myclass.h":
    cdef cppclass MyClass:
        MyClass() except +
        void run(double* X, int N, int D, double* Y)

def run(np.ndarray[np.double_t, ndim=2] X):
    cdef int N, D
    N = X.shape[0]
    D = X.shape[1]

    cdef np.ndarray[np.double_t, ndim=1, mode="c"] X_c
    X_c = np.ascontiguousarray(X, dtype=np.double)

    cdef np.ndarray[np.double_t, ndim=1, mode="c"] Y_c
    Y_c = np.ascontiguousarray(np.zeros((N*D,)), dtype=np.double)

    cdef MyClass myclass
    myclass = MyClass()
    myclass.run(<double*> X_c.data, N, D, <double*> Y_c.data)

    return Y_c.reshape(N, 2)

你基本上是对的。首先,希望优化不是什么大事。理想情况下,大部分时间都在C++内核中使用,而不是在CythNo包装代码中使用。 您可以进行一些风格上的更改来简化代码。(1) 不需要在1D和2D阵列之间重新整形。当你知道数据的内存布局(C++命令与FORTRAN命令、跨步等)时,你可以看到数组只是一块内存,你将用C++来索引自己,所以NUMPY的NDIM在C++方面没有什么关系,只是看到了指针。(2) 使用cython的操作符地址
&
,您可以使用
&X[0,0]
以更简洁的方式获取指向数组开头的指针—无需显式转换

这是我对您的原始代码段的编辑版本:

cimport numpy as np
import numpy as np

cdef extern from "myclass.h":
    cdef cppclass MyClass:
        MyClass() except +
        void run(double* X, int N, int D, double* Y)

def run(np.ndarray[np.double_t, ndim=2] X):
    X = np.ascontiguousarray(X)
    cdef np.ndarray[np.double_t, ndim=2, mode="c"] Y = np.zeros_like(X)

    cdef MyClass myclass
    myclass = MyClass()
    myclass.run(&X[0,0], X.shape[0], X.shape[1], &Y[0,0])

    return Y

你仍然需要在你的
.pyx
文件中
导入numpy作为np
,才能使用numpy函数(
cimport numpy作为np
)。@jorgeca我想你的评论回答了OP问题…@SaulloCastro我把它作为评论发布,因为我认为这是一个小障碍,但我不知道编写这些接口的最佳方式是什么。@jorgeca谢谢,确实是缺少的语句导致了错误消息。你是对的,我主要在寻找优化:-)比如说,这可以用Cython中键入的memoryview来完成,而不是传递数组吗?我不确定这是否会节省一些内存开销,等等?
cimport numpy as np
import numpy as np

cdef extern from "myclass.h":
    cdef cppclass MyClass:
        MyClass() except +
        void run(double* X, int N, int D, double* Y)

def run(np.ndarray[np.double_t, ndim=2] X):
    X = np.ascontiguousarray(X)
    cdef np.ndarray[np.double_t, ndim=2, mode="c"] Y = np.zeros_like(X)

    cdef MyClass myclass
    myclass = MyClass()
    myclass.run(&X[0,0], X.shape[0], X.shape[1], &Y[0,0])

    return Y