sparse python python-2.7 matrix scipy sparse-matrix

sparse - Construyendo y actualizando una matriz dispersa en python usando scipy



sparse matrix python (3)

Crear una segunda matriz con 1 s en sus nuevas coordenadas y agregarla a la existente es una forma posible de hacerlo:

>>> import scipy.sparse as sps >>> shape = (1000, 2000) >>> rows, cols = 1000, 2000 >>> sps_acc = sps.coo_matrix((rows, cols)) # empty matrix >>> for j in xrange(100): # add 100 sets of 100 1''s ... r = np.random.randint(rows, size=100) ... c = np.random.randint(cols, size=100) ... d = np.ones((100,)) ... sps_acc = sps_acc + sps.coo_matrix((d, (r, c)), shape=(rows, cols)) ... >>> sps_acc <1000x2000 sparse matrix of type ''<type ''numpy.float64''>'' with 9985 stored elements in Compressed Sparse Row format>

Intento crear y actualizar una matriz dispersa a medida que leo los datos del archivo. La matriz es de tamaño 100000X40000

¿Cuál es la forma más eficiente de actualizar múltiples entradas de la matriz dispersa? específicamente, necesito incrementar cada entrada por 1.

Digamos que tengo índices de filas [2, 236, 246, 389, 1691]

y índices de columna [117, 3, 34, 2757, 74, 1635, 52]

por lo que todas las siguientes entradas se deben incrementar en uno:

(2,117) (2,3) (2,34) (2,2757) ...

(236,117) (236,3) (236, 34) (236,2757) ...

y así.

Ya estoy usando lil_matrix ya que me dio una advertencia para usar mientras trataba de actualizar una sola entrada.

lil_matrix formato lil_matrix ya no admite actualizaciones múltiples. matrix[1:3,0] += [2,3] me está dando un error no implementado.

Puedo hacerlo ingenuamente, incrementando cada entrada individualmente. Me preguntaba si hay alguna forma mejor de hacer esto, o una mejor implementación de matrices dispersas que pueda usar.

Mi computadora también es una máquina i5 promedio con 4 GB de RAM, así que tengo que tener cuidado de no explotarla :)


Esta respuesta expande el comentario de @ behzad.nouri. Para incrementar los valores en el "producto externo" de sus listas de índices de filas y columnas, simplemente cree estos como matrices numpy configuradas para la transmisión. En este caso, eso significa poner las filas en una columna. Por ejemplo,

In [59]: a = lil_matrix((4,4), dtype=int) In [60]: a.A Out[60]: array([[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]) In [61]: rows = np.array([1,3]).reshape(-1, 1) In [62]: rows Out[62]: array([[1], [3]]) In [63]: cols = np.array([0, 2, 3]) In [64]: a[rows, cols] += np.ones((rows.size, cols.size)) In [65]: a.A Out[65]: array([[0, 0, 0, 0], [1, 0, 1, 1], [0, 0, 0, 0], [1, 0, 1, 1]]) In [66]: rows = np.array([0, 1]).reshape(-1,1) In [67]: cols = np.array([1, 2]) In [68]: a[rows, cols] += np.ones((rows.size, cols.size)) In [69]: a.A Out[69]: array([[0, 1, 1, 0], [1, 1, 2, 1], [0, 0, 0, 0], [1, 0, 1, 1]])


import scipy.sparse rows = [2, 236, 246, 389, 1691] cols = [117, 3, 34, 2757, 74, 1635, 52] prod = [(x, y) for x in rows for y in cols] # combinations r = [x for (x, y) in prod] # x_coordinate c = [y for (x, y) in prod] # y_coordinate data = [1] * len(r) m = scipy.sparse.coo_matrix((data, (r, c)), shape=(100000, 40000))

Creo que funciona bien y no necesita bucles. Estoy siguiendo directamente el doc

<100000x40000 sparse matrix of type ''<type ''numpy.int32''>'' with 35 stored elements in COOrdinate format>