python - ¿Cómo pasar correctamente una matriz CSR scipy.sparse a una función cython?
numpy sparse-matrix (3)
Necesito pasar una matriz CSR scipy.sparse a una función cython. ¿Cómo especifico el tipo, como sería para una matriz numpy?
Aquí hay un ejemplo de cómo acceder rápidamente a los datos de una coo_matrix
usando las propiedades row
, col
y data
. El propósito del ejemplo es simplemente mostrar cómo declarar los tipos de datos y crear los almacenamientos intermedios (también agrega las directivas del compilador que generalmente 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]
Basándose en 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 puede imprimirse en el mismo ciclo.
Para mostrar los datos de 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 compilar un archivo pyx
.
Además, ¿qué cython
su función cython
sobre la matriz? ¿Conoce el formato csr
? El formato coo
?
¿O su función cython
quiere una matriz numpy
regular? En ese caso, estamos en un camino de conejo. Solo necesita convertir la matriz dispersa a 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 puede llamar a esta función usando
some_cython_func(M.data, M.indices, M.indptr)
donde M
es su función CSR
o CSC
.
Consulte esta página para obtener una explicación de los argumentos aprobados sin conversión.