¿Cómo pasar correctamente una matriz CSR scipy.sparse a una función cython?

Necesito pasar una matriz CSR scipy.sparse a una función cython. ¿Cómo especifico el tipo, como uno lo haría para una matriz numpy?

Aquí hay un ejemplo sobre cómo acceder rápidamente a los datos de coo_matrix usando la row propiedades, col y data . El propósito del ejemplo es simplemente mostrar cómo declarar los tipos de datos y crear los buffers (también agregando las directivas del comstackdor que normalmente le darán un impulso considerable) …

 #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] 

Sobre la base de la respuesta de @ SaulloCastro, agregue esta función al archivo .pyx para mostrar los atributos de una matriz 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 no tiene la misma longitud que los data , por lo que no se puede imprimir en el mismo bucle.

Para mostrar los datos csr como coo , puede hacer su propia conversión con estas líneas de iteración:

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

Supongo que sabes cómo configurar y comstackr un archivo pyx .

Además, ¿qué cython tu función cython sobre la matriz? ¿Sabe sobre el formato csr ? ¿El formato coo ?

¿O su función cython quiere una matriz numpy regular? En ese caso, estamos en un camino de conejos. Solo necesita convertir la matriz dispersa en una matriz: x.toarray() (o xA para abreviar).

Si desea acceder a los datos directamente (sin copia) debe especificar el tipo en el argumento de la función:

 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 

Entonces puedes llamar a esta función usando

 some_cython_func(M.data, M.indices, M.indptr) 

donde M es su función CSR o CSC .

Vea esta página para una explicación de pasar un argumento sin lanzar.