2014-07-09 14 views
6

Sto provando a manipolare alcuni dati in una matrice sparsa. Una volta creato uno, come posso aggiungere/modificare/aggiornare i valori in esso? Questo sembra molto semplice, ma non riesco a trovarlo nella documentazione per le classi di matrice sparse o sul web. Penso che mi manchi qualcosa di cruciale.Come si modificano le celle in una matrice sparsa utilizzando scipy?

Questo è il mio tentativo fallito di farlo nello stesso modo in cui vorrei un normale array.

>>> from scipy.sparse import bsr_matrix 
>>> A = bsr_matrix((10,10)) 
>>> A[5][7] = 6 

Traceback (most recent call last): 
    File "<pyshell#11>", line 1, in <module> 
    A[5][7] = 6 
    File "C:\Python27\lib\site-packages\scipy\sparse\bsr.py", line 296, in __getitem__ 
    raise NotImplementedError 
NotImplementedError 

risposta

1

La documentazione per BSR è qui bsr matrix e per la RSI è qui csr matrix. Potrebbe valerne la pena comprendere il CSR prima di passare al bsr. L'unica differenza è che bsr ha voci che sono matrici stesse mentre l'unità di base in un csr è uno scalare.

Non so se ci sono super semplici modi per manipolare le matrici, una volta che sono stati creati, ma qui ci sono alcuni esempi di ciò che si sta cercando di fare,

import numpy as np 
from scipy.sparse import bsr_matrix, csr_matrix 

row = np.array([5]) 
col = np.array([7]) 
data = np.array([6]) 
A = csr_matrix((data,(row,col))) 

Questa è una sintassi semplice in cui vengono elencati tutti i dati desiderati nella matrice nell'array data e quindi specificare dove devono essere utilizzati i dati utilizzando row e col. Si noti che questo renderà le dimensioni della matrice abbastanza grandi da contenere l'elemento nella riga e colonna più grande (in questo caso una matrice 6x8). È possibile visualizzare la matrice in formato standard utilizzando il metodo todense().

A.todense() 

Tuttavia, non è possibile manipolare la matrice al volo utilizzando questo modello. Quello che puoi fare è modificare la rappresentazione nativa di Scipy della matrice. Ciò include 3 attributi, indices, indptr e data. Per cominciare, possiamo esaminare il valore di questi attributi per l'array che abbiamo già creato.

>>> print A.data 
array([6]) 

>>> print A.indices 
array([7], dtype=int32) 

>>> print A.indptr 
array([0, 0, 0, 0, 0, 0, 1], dtype=int32) 

data è la stessa cosa che era prima, una matrice 1-d di valori che vogliamo nella matrice. La differenza è che la posizione di questi dati è ora specificata da indices e indptr anziché da row e da col. indices è abbastanza semplice. Semplicemente un elenco di quale colonna è inserita ogni voce di dati. Sarà sempre la stessa dimensione e l'array data. indptr è un po 'più complicato. Permette la struttura dei dati che cosa riga di ciascuna voce di dati è in. Per citare la documentazione,

gli indici di colonna per fila i sono memorizzati in indices[indptr[i]:indptr[i+1]]

Da questa definizione possiamo vedere che la la dimensione di indptr sarà sempre il numero di righe nella matrice + 1. Ci vuole un po 'di tempo per abituarsi, ma lavorare con i valori per ogni riga ti darà qualche intuito. Si noti che tutte le voci sono zero fino all'ultimo. Ciò significa che gli indici di colonna per le righe i=0-4 verranno memorizzati in indices[0:0], ovvero la matrice vuota. Questo perché queste righe sono tutti zeri. Infine, l'ultima fila, i=5 otteniamo indices[0:1]=7 che ci dice l'immissione dei dati (ies) data[0:1] sono in riga 5, colonna 7.

Ora supponiamo abbiamo voluto aggiungere il valore 10 nella riga 2 colonna 4.Abbiamo prima messo nella attributo data,

A.data = np.array([10,6]) 

successiva abbiamo aggiornare indices per indicare la colonna 10 sarà,

A.indices = np.array([4,7], dtype=np.int32) 

ed infine indichiamo quale riga sarà in modificando indptr

A.indptr = np.array([0,0,0,1,1,1,2], dtype=np.int32) 

e 'importante che si fanno il tipo di dati di indices e indptrnp.int32. Un modo per visualizzare ciò che accade in indptr consiste nel fatto che la modifica dei numeri avviene mentre ci si sposta da i a i+1 di una riga con dati. Si noti inoltre che gli array come questi possono essere usati per costruire matrici sparse

B = csr_matrix((data,indices,indptr)) 

Sarebbe bello se fosse facile come semplicemente indicizzazione nella matrice come si è tentato, ma l'implementazione non c'è ancora. Questo dovrebbe essere sufficiente per iniziare almeno.

5

Esistono diversi formati di matrice Sparse. Alcuni sono più adatti all'indicizzazione. Uno che lo ha implementato è lil_matrix.

Al = A.tolil() 
Al[5,7] = 6 # the normal 2d matrix indexing notation 
print Al 
print Al.A # aka Al.todense() 
A1 = Al.tobsr() # if it must be in bsr format 

La documentazione di ciascun formato suggerisce cosa è buono e dove è male. Ma non ha una lista chiara di quelli che hanno definito le operazioni.

Advantages of the LIL format 
    supports flexible slicing 
    changes to the matrix sparsity structure are efficient 
    ... 
Intended Usage 
    LIL is a convenient format for constructing sparse matrices 
    ... 

dok_matrix implementa inoltre l'indicizzazione.

La struttura dati sottostante per coo_matrix è di facile comprensione. Sono essenzialmente i parametri per la definizione di coo_matrix((data, (i, j)), [shape=(M, N)]). Per creare la stessa matrice è possibile utilizzare:

sparse.coo_matrix(([6],([5],[7])), shape=(10,10)) 

Se si dispone di più incarichi, costruire grandi data, i, j liste (o array 1D), e una volta completato il costrutto matrice sparsa.

Problemi correlati