2012-03-28 7 views
7

Ich möchte ein 2D-Array in eine CSV-Datei mit Zeilen- und Spalten- "Header" Informationen (wie eine Tabelle) speichern. Ich weiß, dass ich das Header-Argument zu numpy.savetxt verwenden kann, um die Spaltennamen zu speichern, aber gibt es eine einfache Möglichkeit, auch ein anderes Array (oder eine Liste) als erste Spalte von Daten (wie Zeilentitel) aufzunehmen?Python/Numpy - Speichern Array mit Spalte und Zeile Titel

Unten ist ein Beispiel, wie ich es derzeit mache. Gibt es eine bessere Möglichkeit, diese Zeilentitel einzubeziehen, vielleicht einen Trick mit savetxt, von dem ich nichts weiß?

import csv 
import numpy as np 

data = np.arange(12).reshape(3,4) 
# Add a '' for the first column because the row titles go there... 
cols = ['', 'col1', 'col2', 'col3', 'col4'] 
rows = ['row1', 'row2', 'row3'] 

with open('test.csv', 'wb') as f: 
    writer = csv.writer(f) 
    writer.writerow(cols) 
    for row_title, data_row in zip(rows, data): 
     writer.writerow([row_title] + data_row.tolist()) 

Antwort

6

Vielleicht würden Sie so etwas wie dies zu tun bevorzugen:

# Column of row titles 
rows = np.array(['row1', 'row2', 'row3'], dtype='|S20')[:, np.newaxis] 
with open('test.csv', 'w') as f: 
    np.savetxt(f, np.hstack((rows, data)), delimiter=', ', fmt='%s') 

Diese implizit data auf ein Array von Strings konvertiert wird, und dauert etwa 200 ms für jede Million Artikel in meinem Computer.

Das dtype '|S20' bedeutet Zeichenfolgen von zwanzig Zeichen. Ist sie zu niedrig ist, erhalten Sie Ihre Zahlen gehackt:

>>> np.asarray([123], dtype='|S2') 
array(['12'], 
    dtype='|S2') 

Eine weitere Möglichkeit, dass aus meiner begrenzten Tests ist langsamer, aber gibt Ihnen viel mehr Kontrolle und haben nicht die Hacken Problem würde np.char.mod verwenden, wie

# Column of row titles 
rows = np.array(['row1', 'row2', 'row3'])[:, np.newaxis] 
str_data = np.char.mod("%10.6f", data) 
with open('test.csv', 'w') as f: 
    np.savetxt(f, np.hstack((rows, str_data)), delimiter=', ', fmt='%s') 
+0

Die Verwendung von Hstack muss das Array im Speicher neu erstellen, richtig? Wenn also Daten sehr groß sind, müssen wir diesen Speicher erneut zuordnen. Für meine spezifische Anwendung ist das wahrscheinlich kein echtes Problem, aber nur ein erwähnenswerter Punkt. Und da ist wahrscheinlich kein Weg. Es scheint etwas zu sein, das savetxt intern implementieren sollte, selbst wenn es eine ähnliche Lösung wie meine (aber im zugrundeliegenden C-Code) hat. –

+0

Ja, du hast Recht. Ich denke, dass vielleicht dieser ganze Overhead mit einem Record-Array vermieden werden könnte und die Tatsache, dass FMT eine Liste von Formatierungsoperatoren akzeptiert, wie 'fmt = ['% s', '% f', ...] ', aber Ich kenne sie nicht, und das ist nur eine Vermutung. – jorgeca

+0

Ya, ich habe auch ein Record-Array in Betracht gezogen. Ich denke, du hast Recht, dass es benutzt werden könnte ... aber ich hatte gehofft, sie zu vermeiden ... Ich denke, ich werde mich einfach für das entscheiden, was das kleinere Übel zu sein scheint. –