我需要将scipy.sparse CSR矩阵传递给cython函数。如何指定类型,就像numpy数组一样?
答案 0 :(得分:5)
以下是有关如何使用属性coo_matrix
,row
和col
快速访问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]
indptr
与data
的长度不同,因此无法在同一循环中打印。
要显示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
是您的CSR
或CSC
函数。
有关在不进行强制转换的情况下传递参数的说明,请参阅this page。