2014-10-20 7 views
6

Ich habe eine MxN Sparse csr_matrix, und ich möchte ein paar Spalten mit nur Nullen auf der rechten Seite der Matrix hinzufügen. Im Prinzip bleiben die Arrays indptr, indices und data gleich, daher möchte ich nur die Dimensionen der Matrix ändern. Dies scheint jedoch nicht implementiert zu sein.Hinzufügen einer Spalte von Nullen zu einer csr_matrix

>>> A = csr_matrix(np.identity(5), dtype = int) 
>>> A.toarray() 
array([[1, 0, 0, 0, 0], 
     [0, 1, 0, 0, 0], 
     [0, 0, 1, 0, 0], 
     [0, 0, 0, 1, 0], 
     [0, 0, 0, 0, 1]]) 
>>> A.shape 
(5, 5) 
>>> A.shape = ((5,7)) 
NotImplementedError: Reshaping not implemented for csr_matrix. 

Auch horizontale Stapelung einer Nullmatrix scheint nicht zu funktionieren.

>>> B = csr_matrix(np.zeros([5,2]), dtype = int) 
>>> B.toarray() 
array([[0, 0], 
     [0, 0], 
     [0, 0], 
     [0, 0], 
     [0, 0]]) 
>>> np.hstack((A,B)) 
array([ <5x5 sparse matrix of type '<type 'numpy.int32'>' 
    with 5 stored elements in Compressed Sparse Row format>, 
     <5x2 sparse matrix of type '<type 'numpy.int32'>' 
    with 0 stored elements in Compressed Sparse Row format>], dtype=object) 

Dies ist, was ich schließlich erreichen möchte. Gibt es einen schnellen Weg, um meine csr_matrix umzuformen, ohne alles darin zu kopieren?

>>> C = csr_matrix(np.hstack((A.toarray(), B.toarray()))) 
>>> C.toarray() 
array([[1, 0, 0, 0, 0, 0, 0], 
     [0, 1, 0, 0, 0, 0, 0], 
     [0, 0, 1, 0, 0, 0, 0], 
     [0, 0, 0, 1, 0, 0, 0], 
     [0, 0, 0, 0, 1, 0, 0]]) 

Antwort

3

Was Sie tun möchten, ist nicht wirklich, was numpy oder scipy als eine Umgestaltung verstehen. Aber für Ihren speziellen Fall, können Sie eine neue CSR-Matrix der data, indices und indptr von Ihrem ursprünglichen Wiederverwendung erstellen, ohne sie zu kopieren:

import scipy.sparse as sps 

a = sps.rand(10000, 10000, density=0.01, format='csr') 

In [19]: %timeit sps.csr_matrix((a.data, a.indices, a.indptr), 
...        shape=(10000, 10020), copy=True) 
100 loops, best of 3: 6.26 ms per loop 

In [20]: %timeit sps.csr_matrix((a.data, a.indices, a.indptr), 
...        shape=(10000, 10020), copy=False) 
10000 loops, best of 3: 47.3 us per loop 

In [21]: %timeit sps.csr_matrix((a.data, a.indices, a.indptr), 
...        shape=(10000, 10020)) 
10000 loops, best of 3: 48.2 us per loop 

Also, wenn Sie nicht mehr benötigen, um Ihre ursprüngliche Matrix a, da der Standard ist copy=False, einfach tun:

a = sps.csr_matrix((a.data, a.indices, a.indptr), shape=(10000, 10020)) 
4

können Sie scipy.sparse.vstack oder scipy.sparse.hstack verwenden, es zu tun schneller:

from scipy.sparse import csr_matrix, vstack, hstack 

B = csr_matrix((5, 2), dtype=int) 
C = csr_matrix((5, 2), dtype=int) 
D = csr_matrix((10, 10), dtype=int) 

B2 = vstack((B, C)) 
#<10x2 sparse matrix of type '<type 'numpy.int32'>' 
#  with 0 stored elements in COOrdinate format> 

hstack((B2, D)) 
#<10x12 sparse matrix of type '<type 'numpy.int32'>' 
#  with 0 stored elements in COOrdinate format> 

Beachten Sie, dass die Ausgabe eine coo_matrix ist, die effizient auf die CSR oder CSC Formate umgewandelt werden können.

Verwandte Themen