如何正确地将scipy.sparse CSR矩阵传递给cython函数?

时间:2014-08-13 20:06:08

标签: python numpy scipy cython sparse-matrix

我需要将scipy.sparse CSR矩阵传递给cython函数。如何指定类型,就像numpy数组一样?

3 个答案:

答案 0 :(得分:5)

以下是有关如何使用属性coo_matrixrowcol快速访问data数据的示例。该示例的目的只是为了说明如何声明数据类型并创建缓冲区(还添加通常会给您带来相当大提升的编译器指令)...

#cython: boundscheck=False
#cython: wraparound=False
#cython: cdivision=True
#cython: nonecheck=False

import numpy as np
from scipy.sparse import coo_matrix
cimport numpy as np

ctypedef np.int32_t cINT32
ctypedef np.double_t cDOUBLE

def print_sparse(m):
    cdef np.ndarray[cINT, ndim=1] row, col
    cdef np.ndarray[cDOUBLE, ndim=1] data
    cdef int i
    if not isinstance(m, coo_matrix):
        m = coo_matrix(m)
    row = m.row.astype(np.int32)
    col = m.col.astype(np.int32)
    data = m.data.astype(np.float64)
    for i in range(np.shape(data)[0]):
        print row[i], col[i], data[i]

答案 1 :(得分:3)

在@ SaulloCastro的答案的基础上,将此函数添加到.pyx文件中以显示csr矩阵的属性:

def print_csr(m):
    cdef np.ndarray[cINT32, ndim=1] indices, indptr
    cdef np.ndarray[cDOUBLE, ndim=1] data
    cdef int i
    if not isinstance(m, csr_matrix):
        m = csr_matrix(m)
    indices = m.indices.astype(np.int32)
    indptr = m.indptr.astype(np.int32)
    data = m.data.astype(np.float64)
    print indptr
    for i in range(np.shape(data)[0]):
        print indices[i], data[i]

indptrdata的长度不同,因此无法在同一循环中打印。

要显示csr这样的coo数据,您可以使用这些迭代行进行自己的转换:

    for i in range(np.shape(indptr)[0]-1):
        for j in range(indptr[i], indptr[i+1]):
            print i, indices[j], data[j]

我假设您知道如何设置和编译pyx文件。

另外,您的cython函数对矩阵有什么假设?它是否知道csr格式? coo格式?

或者您的cython函数是否需要常规numpy数组?在那种情况下,我们走了一条兔子小道。您只需将稀疏矩阵转换为数组:x.toarray()(或简称为x.A)。

答案 2 :(得分:2)

如果要直接访问数据(无需复制),则需要在函数参数中指定类型:

import numpy as np
cimport numpy as np

#cython: boundscheck=False
#cython: wraparound=False
def some_cython_func(np.ndarray[np.double_t] data, np.ndarray[int] indices, np.ndarray[int] indptr):
    #body of of the function

然后你可以使用

调用这个函数
some_cython_func(M.data, M.indices, M.indptr)

其中M是您的CSRCSC函数。

有关在不进行强制转换的情况下传递参数的说明,请参阅this page