将numpy整数数组传递给c代码
我正在尝试编写Cython代码,以比sklearn的内置代码更快地将密集特征矩阵、目标向量对转储为libsvm格式。我得到一个编译错误,抱怨将目标向量(int的numpy数组)传递给相关的c函数时出现了类型问题 代码如下:将numpy整数数组传递给c代码,numpy,cython,python-extensions,Numpy,Cython,Python Extensions,我正在尝试编写Cython代码,以比sklearn的内置代码更快地将密集特征矩阵、目标向量对转储为libsvm格式。我得到一个编译错误,抱怨将目标向量(int的numpy数组)传递给相关的c函数时出现了类型问题 代码如下: import numpy as np cimport numpy as np cimport cython cdef extern from "cdump.h": int filedump( double features[], int numexemplars,
import numpy as np
cimport numpy as np
cimport cython
cdef extern from "cdump.h":
int filedump( double features[], int numexemplars, int numfeats, int target[], char* outfname)
@cython.boundscheck(False)
@cython.wraparound(False)
def fastdumpdense_libsvmformat(np.ndarray[np.double_t,ndim=2] X, y, outfname):
if X.shape[0] != len(y):
raise ValueError("X and y need to have the same number of points")
cdef int numexemplars = X.shape[0]
cdef int numfeats = X.shape[1]
cdef bytes py_bytes = outfname.encode()
cdef char* outfnamestr = py_bytes
cdef np.ndarray[np.double_t, ndim=2, mode="c"] X_c
cdef np.ndarray[np.int_t, ndim=1, mode="c"] y_c
X_c = np.ascontiguousarray(X, dtype=np.double)
y_c = np.ascontiguousarray(y, dtype=np.int)
retval = filedump( &X_c[0,0], numexemplars, numfeats, &y_c[0], outfnamestr)
return retval
当我试图使用distutils编译这段代码时,我得到了错误
cythoning fastdump_svm.pyx to fastdump_svm.cpp
Error compiling Cython file:
------------------------------------------------------------ ...
cdef np.ndarray[np.double_t, ndim=2, mode="c"] X_c
cdef np.ndarray[np.int_t, ndim=1, mode="c"] y_c
X_c = np.ascontiguousarray(X, dtype=np.double)
y_c = np.ascontiguousarray(y, dtype=np.int)
retval = filedump( &X_c[0,0], numexemplars, numfeats, &y_c[0], outfnamestr)
^
------------------------------------------------------------
fastdump_svm.pyx:24:58: Cannot assign type 'int_t *' to 'int *'
你知道如何修复这个错误吗?我最初遵循的是传递y_.c.数据的范例,这很有效,但这显然不是推荐的方式。问题是
numpy.int_/code>与int
不同,您可以通过让程序打印sizeof(numpy.int_t)
和sizeof(int)
来轻松检查这一点
int
是一个c int,由c标准定义为至少16位,但在我的机器上是32位numpy.int\u t
通常是32位或64位,这取决于您使用的是32位还是64位版本的numpy,但当然也有一些例外(可能是windows用户)。如果您想知道哪个numpy数据类型与您的c_int匹配,可以执行np.dtype(cytpes.c_int)
因此,要将numpy数组传递给c代码,可以执行以下操作:
import ctypes
cdef np.ndarray[int, ndim=1, mode="c"] y_c
y_c = np.ascontiguousarray(y, dtype=ctypes.c_int)
retval = filedump( &X_c[0,0], numexemplars, numfeats, &y_c[0], outfnamestr)
在启动numpy数组以匹配计算机上的Cint
时,也可以使用dtype=np.dtype(“i”)
cdef int [:] y_c
c_array = np.ascontiguousarray(y, dtype=np.dtype("i"))
cdef中的数据类型应为int\u t,否?当我在没有int的情况下尝试时,我得到一个错误,即无法将指针强制转换到Python对象。当我使用int_t时,我得到了与以前相同的错误,关于从int_t*到int*的转换。对不起,我上次的评论,我似乎误解了你接下来的问题。cdef应具有与filedump
的函数声明相同的类型,因此如果参数定义为int target[]
,cdef应使用int
。例如,如果您可以更改filedump
的签名,您可以将它们都设置为np.int\u t
,但它们应该相同。确保您使用的是int
而不是np.int
,第一个是c基本类型(至少在cdef块中使用时是这样),第二个是python类型。