Seite 1 von 1
string und array in ascii datei speichern
Verfasst: Freitag 10. Mai 2013, 09:55
von pynew
Hey Leute, ich habe nun angefangen in Python zu programmieren. Dies ist meine erste Programmiersprache die ich lerne und nun bin ich auf ein Problem gestoßen, das mir ehrlich gesagt kopf zerbrechen bereitet
ich habe schon gesucht, aber nichts dazu gefunden, hoffe ihr könnt mir helfen
im prinzip möchte ich in die erste Zeile einer .asc Datei die Variablen "t", "x" und "y" schreiben.
und darunten in Spalten die Matrix. Man kann sich dies also als Messung vorstellen, die Zeitwerte t und in meinem Beispiel stellt sin(t) x dar und cos(t) ist y. Die matrix mit den Werten ist ein array und die erste Zeile mit den Variablen ist ein String, oder kann man das anders implementieren?
aber hier jetzt mal mein code:
Code: Alles auswählen
import numpy as np
t=np.arange(0.0,10.0,0.5)
x=np.sin(t)
y=np.cos(t)
M=np.column_stack((t.T,x.T,y.T)) # M ist Matrix, in der als Spalten die Werte t,x,y stehen
print M
g="{0:5}{1:11}{1:6}{2:12}{2:7}{3:13}"
c=(g.format(" ","t"," ","x"," ","y"))
h="\n"\
f=open("save.asc","w")
f.write(c)
f.write(h)
np.savetxt("save.asc",M,fmt="%15.6e")
f.close()
b=np.genfromtxt("save.asc")
print b
und das Ergebnis was herauskommt ist:
Code: Alles auswählen
t t x 000000e-01 4.794255e-01 8.775826e-01
1.000000e+00 8.414710e-01 5.403023e-01
1.500000e+00 9.974950e-01 7.073720e-02
2.000000e+00 9.092974e-01 -4.161468e-01
2.500000e+00 5.984721e-01 -8.011436e-01
3.000000e+00 1.411200e-01 -9.899925e-01
3.500000e+00 -3.507832e-01 -9.364567e-01
4.000000e+00 -7.568025e-01 -6.536436e-01
4.500000e+00 -9.775301e-01 -2.107958e-01
5.000000e+00 -9.589243e-01 2.836622e-01
5.500000e+00 -7.055403e-01 7.086698e-01
6.000000e+00 -2.794155e-01 9.601703e-01
6.500000e+00 2.151200e-01 9.765876e-01
7.000000e+00 6.569866e-01 7.539023e-01
7.500000e+00 9.380000e-01 3.466353e-01
8.000000e+00 9.893582e-01 -1.455000e-01
8.500000e+00 7.984871e-01 -6.020119e-01
9.000000e+00 4.121185e-01 -9.111303e-01
9.500000e+00 -7.515112e-02 -9.971722e-01
also es sollte nicht t,t,x in der ersten Zeile stehen, sondern t,x,y
die werte in der ersten Zeile am schluss gehören dort auch nicht hin.
Hoffe mir kann jemand helfen, hab schon ewig rumprobiert, aber bin auf nichts vernünftiges gekommen :K
Ah und falls das im falschen Unterforum stehen sollte, bitte verschiebt es, ich wusste nicht wo genau hin damit

Re: string und array in ascii datei speichern
Verfasst: Freitag 10. Mai 2013, 10:12
von Sirius3
Hallo pynew,
schau Dir in der Dokumentation nochmal an was »str.format« macht. Vor allem, wie man in angibt, welches der Argumente benutzt werden soll.
Zum zweiten Problem: Du schreibst zweimal in die gleiche Datei "save.asc" mit verschiedenen Filehandles gleichzeitig. Was in welcher Reihenfolge dann in der Datei steht ist damit undefiniert. Zum Glück kann »np.savetxt« auch in Filehandles schreiben, dann tritt das Problem nicht auf.
Re: string und array in ascii datei speichern
Verfasst: Freitag 10. Mai 2013, 10:13
von BlackJack
@pynew: Das da 't' zweimal geschrieben wird, liegt daran, dass *Du* sagst, das es zweimal geschrieben werden soll. Vielleicht solltest Du das `format()` nicht so unnötig kompliziert machen, dann blickt man da einfacher durch welcher Wert, wie und wohin formatiert wird. Man muss da auch nicht jedes Zwischenergebnis an einen eigenen Namen binden und auch das Zeilenendezeichen kann man direkt in die Formatvorlage schreiben, statt es separat zu schreiben.
Das Schreiben in die Datei kann so grundsätzlich nicht funktionieren, weil die Datei zweimal zum Schreiben geöffnet wird. Einmal explizit mit `open()` und dann noch mal innerhalb von `np.savetxt()`. Welcher Teil von diesen beiden Schreiboperationen dann wo in der Datei landet, beziehungsweise ob überhaupt, ist mehr oder weniger Zufall, beziehungsweise hängt von Faktoren wie Puffergrössen des Betriebssystems ab, die nicht unter der Kontrolle des Programmierers sind. Du darfst da keinen Dateinamen übergeben, sondern musst das selbe Dateiobjekt übergeben in dass Du auch schon die Kopfzeile geschrieben hast.
Zum Öffnen von Dateien sollte man die ``with``-Anweisung verwenden, damit die Datei auch unter allen Umständen wieder geschlossen wird.
Re: string und array in ascii datei speichern
Verfasst: Freitag 10. Mai 2013, 10:19
von /me
pynew hat geschrieben:Code: Alles auswählen
g="{0:5}{1:11}{1:6}{2:12}{2:7}{3:13}"
c=(g.format(" ","t"," ","x"," ","y"))
Zu Beginn möchte ich dir den Hinweis geben dir mal
PEP-8, den Style Guide für Python anzusehen.
So sieht es besser aus.
Code: Alles auswählen
header_template = "{0:5}{1:11}{1:6}{2:12}{2:7}{3:13}"
header = header_template.format(" ","t"," ","x"," ","y")
Oder direkt so.
Code: Alles auswählen
header = "{0:5}{1:11}{1:6}{2:12}{2:7}{3:13}".format(" ","t"," ","x"," ","y")
Jetzt hast du ein Problem mit der Ausgabe der ersten Zeile. Es erscheinen nicht die Werte die du erwartest. Andererseits macht Python hier alles richtig. Der erste zu ersetzende Ausdruck im Format-String ist
{0:5}. Du bekommst dort den ersten Parameter (Index 0) auf 5 Zeichen aufgefüllt. Danach kommt dann {1:11} und danach wird es dann merkwürdig. Mit {1:6} greifst du wieder auf den gleichen Parameterwert zu. Anscheinend hast du das Hochzählen vergessen.
Den Zeilenumbruch könntest du übrigens direkt in den Formatstring hineinnehmen.
Code: Alles auswählen
header = '{0:5}{1:11}{2:6}{3:12}{4:7}{5:13}\n'.format(' ', 't', ' ', 'x', ' ', 'y')
Mir ist allerdings noch nicht klar, warum du hier überhaupt einen Formatstring verwendest oder nicht zumindest die Leerzeichen aus der Parameterliste in den String verlagerst.
Re: string und array in ascii datei speichern
Verfasst: Freitag 10. Mai 2013, 10:32
von pynew
klasse, danke euch erstmal für die schnellen Antworten.
neuer code:
Code: Alles auswählen
import numpy as np
t=np.arange(0.0,10.0,0.5)
x=np.sin(t)
y=np.cos(t)
M=np.column_stack((t.T,x.T,y.T))
print M
#g="{0:12}{1:12}{2:12}"
#c=(g.format("t","x","y\n"))
header = '{0:5}{1:11}{2:6}{3:12}{4:7}{5:13}\n'.format(' ', 't', ' ', 'x', ' ', 'y')
with open("save.asc","w") as f:
f.write(header)
np.savetxt("save.asc",M,fmt="%15.6e")
f.close()
#b=np.loadtxt("save.asc")
b=np.genfromtxt("save.asc")
print b
und was rauskommt:
Code: Alles auswählen
t x y
0000e-01 4.794255e-01 8.775826e-01
1.000000e+00 8.414710e-01 5.403023e-01
1.500000e+00 9.974950e-01 7.073720e-02
2.000000e+00 9.092974e-01 -4.161468e-01
2.500000e+00 5.984721e-01 -8.011436e-01
3.000000e+00 1.411200e-01 -9.899925e-01
3.500000e+00 -3.507832e-01 -9.364567e-01
4.000000e+00 -7.568025e-01 -6.536436e-01
4.500000e+00 -9.775301e-01 -2.107958e-01
5.000000e+00 -9.589243e-01 2.836622e-01
5.500000e+00 -7.055403e-01 7.086698e-01
6.000000e+00 -2.794155e-01 9.601703e-01
6.500000e+00 2.151200e-01 9.765876e-01
7.000000e+00 6.569866e-01 7.539023e-01
7.500000e+00 9.380000e-01 3.466353e-01
8.000000e+00 9.893582e-01 -1.455000e-01
8.500000e+00 7.984871e-01 -6.020119e-01
9.000000e+00 4.121185e-01 -9.111303e-01
9.500000e+00 -7.515112e-02 -9.971722e-01
also mit der ersten Zeile passt das jetzt so.
Weshalb ich das mit Format machen?
Anfangs habe ich das so probiert:
aber das hat mich nicht weitergebracht, deshalb habe ich mir gedacht, es könnte ja mit .format funktionieren und hab das dann probiert
oder gäbe es einen einfacheren Weg?
Genau das ist mein Problem im Moment, ich möchte in die gleiche Datei, zuerst die Kopfzeile und dann die Werte einlesen, so dass sie "geordnet" in richtiger Reihenfolge herauskommen. Wie kann ich das am besten angehen?
und @sirius3 , sorry, aber was heißt "Filehandles" ?

wie gesagt, bin voller Anfänger

Re: string und array in ascii datei speichern
Verfasst: Freitag 10. Mai 2013, 10:41
von Sirius3
@pynew: den Zeilenumbruch würde ich noch in den Formattext und nicht in die Argumente nehmen.
Mit Filehandle meine ich eigentlich ein Fileobjekt, bei Dir »f«. Wenn Du nun noch in »savetxt« statt des ersten Arguments "save.asc" »f« schreibst, müsste alles so sein, wie Du erwartest.
Re: string und array in ascii datei speichern
Verfasst: Freitag 10. Mai 2013, 10:50
von pynew
danke dir sirius!
Code: Alles auswählen
import numpy as np
t=np.arange(0.0,10.0,0.5)
x=np.sin(t)
y=np.cos(t)
M=np.column_stack((t.T,x.T,y.T))
print M
header = '{0:9}{1:11}{2:6}{3:10}{4:5}{5:13}'.format(' ', 't', ' ', 'x', ' ', 'y\n')
with open("save.asc","w") as f:
f.write(header)
np.savetxt(f,M,fmt="%15.4e")
f.close()
b=np.genfromtxt("save.asc")
print b
aber letztes Problem, die erste Zeile der Matrix ist verschoben, wodurch wird das verursacht?
Code: Alles auswählen
t x y
0.0000e+00 0.0000e+00 1.0000e+00
5.0000e-01 4.7943e-01 8.7758e-01
1.0000e+00 8.4147e-01 5.4030e-01
1.5000e+00 9.9749e-01 7.0737e-02
2.0000e+00 9.0930e-01 -4.1615e-01
2.5000e+00 5.9847e-01 -8.0114e-01
3.0000e+00 1.4112e-01 -9.8999e-01
3.5000e+00 -3.5078e-01 -9.3646e-01
4.0000e+00 -7.5680e-01 -6.5364e-01
4.5000e+00 -9.7753e-01 -2.1080e-01
5.0000e+00 -9.5892e-01 2.8366e-01
5.5000e+00 -7.0554e-01 7.0867e-01
6.0000e+00 -2.7942e-01 9.6017e-01
6.5000e+00 2.1512e-01 9.7659e-01
7.0000e+00 6.5699e-01 7.5390e-01
7.5000e+00 9.3800e-01 3.4664e-01
8.0000e+00 9.8936e-01 -1.4550e-01
8.5000e+00 7.9849e-01 -6.0201e-01
9.0000e+00 4.1212e-01 -9.1113e-01
9.5000e+00 -7.5151e-02 -9.9717e-01
und allgemeine Fragen noch:
- wenn ich ein array wie hier in eine Datei schreiben möchte, nutze ich den Befehl np.savetxt oder gibts dazu alternativen?
- und wenn ich die datei lesen will, muss ich np.genfromtxt nutzen, weil ein array drin ist, und ein "normaler" "read"-Befehl, dieses array nicht lesen kann oder? gibts dazu alternativen? np.loadtxt kann ja nur dateien laden, in denen keine Strings stehen, oder hab ich das falsch verstanden?
Re: string und array in ascii datei speichern
Verfasst: Freitag 10. Mai 2013, 11:35
von nomnom
pynew hat geschrieben:Code: Alles auswählen
header = '{0:9}{1:11}{2:6}{3:10}{4:5}{5:13}'.format(' ', 't', ' ', 'x', ' ', 'y\n')
aber letztes Problem, die erste Zeile der Matrix ist verschoben, wodurch wird das verursacht?
Das liegt daran, dass es den String
'y\n' rechts auffüllt, und da entsteht dann eben das hier:
Außerdem benutzt man
with gerade deshalb, weil man da die Datei nicht explizit schließen muss. Die Zeile
f.close() ist falsch.
Re: string und array in ascii datei speichern
Verfasst: Freitag 10. Mai 2013, 11:37
von Sirius3
@pynew: schau Dir nochmal genau an, wie Dein »header« aussieht

und beachte meine erste Anmerkung.
Es gibt viele Möglichkeiten aus Textdateien Arrays zu lesen, aber kaum einfachere. Aber was stört Dich an »genfromtext« genau jetzt?
Re: string und array in ascii datei speichern
Verfasst: Freitag 10. Mai 2013, 11:40
von BlackJack
@pynew: Die verschobene zweite Zeile liegt daran, dass Du das Zeilenende-Zeichen an der falschen Stelle eingefügt hast. Das ist doch gar nicht Teil der letzten Spaltenüberschrift, sondern sollte ans *Ende* der Zeile. Also in die Formatvorlage für die Zeile.
`numpy.savetext()` bietet sich hier an, weil es das halt schon gibt und das anscheinend die Daten in einem Format schreibt, welches Du haben möchtest.
Zum Lesen kann man auch `numpy.loadtext()` nehmen. Denn die Daten enthalten ja nur Zahlen. Die Kopfzeile müsstest Du bei beiden Funktionen mit dem entsprechenden Argument (`skip_header`) ignorieren.
Re: string und array in ascii datei speichern
Verfasst: Freitag 10. Mai 2013, 11:54
von pynew
Gracias, also es schaut so aus, wie ich es mir vorgestellt habe
Code: Alles auswählen
import numpy as np
t=np.arange(0.0,10.0,0.5)
x=np.sin(t)
y=np.cos(t)
M=np.column_stack((t.T,x.T,y.T))
#print M
header = '{0:9}{1:11}{2:6}{3:10}{4:5}{5:2}'.format(' ', 't', ' ', 'x', ' ', 'y\n')
with open("save.asc","w") as f:
f.write(header)
np.savetxt(f,M,fmt="%15.4e")
b=np.genfromtxt("save.asc")
print b
und kommt schön raus:
Code: Alles auswählen
t x y
0.0000e+00 0.0000e+00 1.0000e+00
5.0000e-01 4.7943e-01 8.7758e-01
1.0000e+00 8.4147e-01 5.4030e-01
1.5000e+00 9.9749e-01 7.0737e-02
2.0000e+00 9.0930e-01 -4.1615e-01
2.5000e+00 5.9847e-01 -8.0114e-01
3.0000e+00 1.4112e-01 -9.8999e-01
3.5000e+00 -3.5078e-01 -9.3646e-01
4.0000e+00 -7.5680e-01 -6.5364e-01
4.5000e+00 -9.7753e-01 -2.1080e-01
5.0000e+00 -9.5892e-01 2.8366e-01
5.5000e+00 -7.0554e-01 7.0867e-01
6.0000e+00 -2.7942e-01 9.6017e-01
6.5000e+00 2.1512e-01 9.7659e-01
7.0000e+00 6.5699e-01 7.5390e-01
7.5000e+00 9.3800e-01 3.4664e-01
8.0000e+00 9.8936e-01 -1.4550e-01
8.5000e+00 7.9849e-01 -6.0201e-01
9.0000e+00 4.1212e-01 -9.1113e-01
9.5000e+00 -7.5151e-02 -9.9717e-01
Danke euch nochmal an dieser Stelle.
Wegen den Befehlen hab ich hauptsächlich aus Interesse gefragt.
Aber jetzt möchte ich die Datei save.asc wieder einlesen und es soll dann am Schluss so zugewiesen sein, dass steht:
t=1.Spalte
x=2.Spalte
y=3.Spalte
Mit dem Befehl "genfromtxt" liest er mir das im Interpreter so ein:
Code: Alles auswählen
[[ nan nan nan]
[ 0. 0. 1. ]
[ 0.5 0.47943 0.87758 ]
[ 1. 0.84147 0.5403 ]
[ 1.5 0.99749 0.070737]
[ 2. 0.9093 -0.41615 ]
[ 2.5 0.59847 -0.80114 ]
[ 3. 0.14112 -0.98999 ]
[ 3.5 -0.35078 -0.93646 ]
[ 4. -0.7568 -0.65364 ]
[ 4.5 -0.97753 -0.2108 ]
[ 5. -0.95892 0.28366 ]
[ 5.5 -0.70554 0.70867 ]
[ 6. -0.27942 0.96017 ]
[ 6.5 0.21512 0.97659 ]
[ 7. 0.65699 0.7539 ]
[ 7.5 0.938 0.34664 ]
[ 8. 0.98936 -0.1455 ]
[ 8.5 0.79849 -0.60201 ]
[ 9. 0.41212 -0.91113 ]
[ 9.5 -0.075151 -0.99717 ]]
sprich, er erkennt t,x,y nicht an.
Ich bastel mal ein bisschen rum, wenn ich häng, mach ich wieder meldung

danke nochmal!
Re: string und array in ascii datei speichern
Verfasst: Freitag 10. Mai 2013, 12:19
von BlackJack
@pynew: Die erste Zeile enthält ja auch keine Zahlen und Typen mischen geht in so einem Array nicht. Liest Du meine Beiträge überhaupt? Ich habe das überlesen der Kopfzeile mit dem `skip_header`-Argument jetzt schon zweimal erwähnt.
Die erste Zeile ist egal, Du wirst den Inhalt dort beim Einlesen nicht verwenden. Die Namen für die Spalten schreibst Du im Quelltext noch mal hin. Die werden nicht auf magische Weise aus der Eingabedatei erzeugt. So etwas will man auch gar nicht haben, denn dann könnten beliebige Dateien beliebige Namen neu binden, die man vielleicht schon für etwas anderes verwendet hat. Da ist Chaos und schwer auffindbare Fehler vorprogrammiert.
Für das verteilen der Spalten auf Namen kann man Tupel-Unpacking und das `unpack`-Argument von `numpy.loadtxt()` oder `numpy.genfromtxt()` verwenden. Die Dokumentation hat ein Beispiel dazu beim `unpack`-Argument.