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>