2016-05-20 3 views
2

Ich habe eine 0,15 M x 1,3 M Sparse.lil-Matrix, die ich in einer CSV-Datei speichern möchte. Wie kann ich es in einer CSV-Datei speichern, so dass die resultierende Dateigröße am kleinsten ist. Nach mir der beste Weg, es alsSpeichern Sie eine Sparse.LIL-Matrix zu Csv in Python

# output.csv 

row1 col1 v11 
row1 col2 v12 
row1 col7 v17 
row1 col9 v19 
row2 col3 v23 
row2 col6 v26 

speichern wird, wo Werte v ij nur Werte ungleich Null sind.

Gibt es (direkte) Funktion (en), die dies tun können? Ich vermute, es wird sehr teuer sein, es Element für Element zu tun!

Antwort

3

Die dünn besetzten Matrixformate speichern nur die Werte ungleich Null, daher ist das Schreiben dieser Werte die kompakteste Option. Aber lil ist eine Liste des Listenformats, das nicht das Format ist, das Sie schreiben möchten.

Aber coo Format speichert seine Daten in 3 Attribute, Zeile, Spalte und Daten, die die gewünschten Werte sind.

scipy.io hat ein savemat Format, das spärlich verarbeitet, aber es ist eine MATLAB-Datei. Ich kenne keine anderen Optionen in scipy.io.

Sind die Werte ganze Zahlen? Das wird am einfachsten sein. Hier verkette ich die 3 Attributarrays des coo Formats in ein Nx3-Array und speichere es dann in einer Textdatei mit dem üblichen np.savetxt.

In [649]: M = sparse.eye(10).tolil() 

In [650]: Mc = M.tocoo() 

In [651]: Mc.row,Mc.col,Mc.data 
Out[651]: 
(array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=int32), 
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=int32), 
array([ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])) 

In [652]: A=np.column_stack((Mc.row,Mc.col,Mc.data)) 

In [653]: A.shape 
Out[653]: (10, 3) 

In [655]: np.savetxt('lil.txt',A, fmt='%5.d',delimiter=',') 

In [656]: cat lil.txt 
    0, 0, 1 
    1, 1, 1 
    2, 2, 1 
    ... 
    7, 7, 1 
    8, 8, 1 
    9, 9, 1 

Die Bildung des Arrays wird schnell sein. Das Schreiben dauert einige Zeit, da np.savetxt die Arrayzeilen durchläuft und Zeile für Zeile schreibt. Aber seien Sie ehrlich, alle Textdateien werden Zeile für Zeile geschrieben, oder?

f.write(fmt % tuple(row)) 

Dies ist das Format des lil Array:

In [658]: M.rows 
Out[658]: array([[0], [1], [2], [3], [4], [5], [6], [7], [8], [9]], dtype=object) 

In [659]: M.data 
Out[659]: array([[1.0], [1.0], [1.0], [1.0], [1.0], [1.0], [1.0], [1.0], [1.0], [1.0]], dtype=object) 

tatsächlich durch M Datenwerte erzeugt, wie float. Und das A Array ist auch float. So konnte ich mit einem Float-Format speichern, z. np.savetxt('lil.txt',A, fmt='%10.5f',delimiter=',')

np.savetxt('lil.txt',A, fmt='%10d,%10d,%10.5f') schreibt 2 Ganzzahlspalten und einen Float.

Wenn Sie einige der ganzzahligen Indexwerte nicht wie geschrieben mögen, müssen wir möglicherweise A als ein strukturiertes Array bilden.

====================

Eine weitere Möglichkeit ist es, die Linien direkt zu schreiben. Basierend auf dem, was ich von np.savetxt weiß, kann dies genauso schnell sein.

In [678]: with open('lil.txt','wb') as f: 
    for x in zip(Mc.row,Mc.col,Mc.data): 
     f.write(b'%5d,%5d,%10f\n'%x) 
    .....:   

In [679]: cat lil.txt 
    0, 0, 1.000000 
    1, 1, 1.000000 
    2, 2, 1.000000 
    ... 
    8, 8, 1.000000 
    9, 9, 1.000000