Array in Textdatei schreiben

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
ConanDerBarbar
User
Beiträge: 19
Registriert: Donnerstag 21. März 2019, 00:52

Hallo,

ich habe das Forum durchsucht und keine Lösung für mein Problem (mehr ein Schönheitsmakel als ein wirkliches Problem) gefunden. Ich bin zwar kein kompletter Neuling in Python, tue mir mit einigen Sachen dennoch schwer.

Ich bin gerade dabei ein Programm zu schreiben, bei dem Arrays einer bestimmten Größe alle 10 Minuten in eine Textdatei geschrieben werden sollen ohne, dass der vorherige Inhalt verloren geht. Dabei soll der Inhalt des Arrays jedoch ohne Komas und Klammer in die entsprechenden Zeilen und Spalten geschrieben werden.

Ich habe bereits ein Programmcode der funktioniert, bin nur einfach noch nicht richtig zufrieden damit. Hier ein Beispiel

Code: Alles auswählen

import numpy as np

vT = np.full((2,3), np.nan)

vT[1, 0] = 1
vT[0, 1] = 2

doc = open("Hey.txt", 'a')

for i in range(2):
    for j in range(3):
        doc.write(str(vT[i, j]) + '\t')
    doc.write('\n')
        
doc.close()

Die Ausgabe sieht in dem Beispielprogramm so aus:
nan 2.0 nan
1.0 nan nan
nan 2.0 nan
1.0 nan nan
nan 2.0 nan
1.0 nan nan
nan 2.0 nan
1.0 nan nan

Meine Frage: Gibt es einen eleganteren Weg das hinzubekommen?

Grüße
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

np.savetxt?

Wenn man über einen Index iteriert, macht man in den allermeisten Fällen etwas falsch. Dateien öffnet man am besten mit dem with-Statement. Benutze aussagekräftige Variablennamen, vT ist nur eine kryptische Abkürzung.
ConanDerBarbar
User
Beiträge: 19
Registriert: Donnerstag 21. März 2019, 00:52

np.savetxt ist für meinen Fall nicht brauchbar, da dieser mir mein Array in eine Zeile klatsch und nicht auf \t oder \n reagiert. Zudem wenn ich ein neues Array mit neuen Werten in die Textdatei anhängen will, überschreibt es immer das erste.

Das Array muss in der Textdatei dieselbe Struktur aufweisen wie im Original Array, nur ohne die Klammern.

Mit den Namen hast du Recht. Hab nur das kleine Beispielprogramm einfach abgeschrieben. Ich weis was die Variablen bedeuten und alle anderen in dem Bereich auch, aber fürs Forum ist es vermutlich blöd.

Grüße
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@ConanDerBarbar: Du hast Dir np.savetxt nicht genau genug angeschaut. Alles was Du brauchst, kannst Du damit machen. Was hast Du denn versucht?
ConanDerBarbar
User
Beiträge: 19
Registriert: Donnerstag 21. März 2019, 00:52

@Sirius3 Ich habe die delimiter und newline Properties gesetzt mit \t und \n aber diese wurden nicht umgesetzt. Ich weis nicht wie ich dem Programm sonst sagen soll, dass er Tab und Enter macht. Vielleicht habe ich es auch übersehen, aber ich habe nichts gesehen wie ich neue Arrays anhängen kann. So etwas wie Header, Footer, Comments brauche ich ja nicht.
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Statt zu beschreiben, was Du gemacht hast, poste doch den Code. Und zeige, was die Ausgabe ist, und wie Du sie statt dessen vorstellst.
Benutzeravatar
__blackjack__
User
Beiträge: 13112
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@ConanDerBarbar: Du hast „Properties gesetzt“? Vielleicht solltest Du einfach mal zeigen was Du gemacht hast. Um an eine Datei anzuhängen öffnet man sie im `mode` 'a' für 'append' — das weisst Du doch aber schon‽

Das Originalarray hat keine Klammern und irgendeine Struktur die Du nicht kennst, und im Grunde auch nicht kennen musst. Es ist auf jeden Fall nicht Text.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
ConanDerBarbar
User
Beiträge: 19
Registriert: Donnerstag 21. März 2019, 00:52

Das ich append benutzen muss, weis ich, deshalb habe ich es bei der open Funktion oben angewandt. Ich wusste nur nicht, dass es das bei np.savetxt() auch gibt. Habe zumindest nichts in der Funktionsbeschreibung gefunden, oder kann man das bei der fmt-Property mit reinpacken?

Mit Properties meine ich folgendes:

Code: Alles auswählen

import numpy as np


vT = np.full((2,3), np.nan)

vT[1, 0] = 1
vT[0, 1] = 2

np.savetxt("Hey.txt", vT, delimiter = '\t', newline = '\n')
Ausgabe in Texdatei:
nan 2.000000000000000000e+00 nan 1.000000000000000000e+00 nan nan

Wenn ich es richtig verstanden habe gibt es bei np.savetxt() doch die Property fmt, mit der ich die Zahlen Formatieren kann, sodass sie nur 2 Nachkommastellen haben, oder?

Das wäre nämlich ein weiteres Problem bei np.savetxt()



Mit den Klammern meine ich nur das:

Code: Alles auswählen

import numpy as np

vT = np.full((2,3), np.nan)

vT[1, 0] = 1
vT[0, 1] = 2

doc = open("Hey.txt", 'a')

doc.write(str(vT))
        
doc.close()
Ausgabe in die Textdatei:
[[ nan 2. nan]
[ 1. nan nan]]

Das war nur mein erster Versuch, und da sind halt die eckigen Klammern in den man Array definieren kann mit in der Ausgabe. Die Ausgabe soll aber so aussehen wie in meinem Ursprünglichen Post.
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@ConanDerBarbar: dann hast Du ein Darstellungsproblem. Die Tabelle wird in mehrere Zeilen geschrieben.

Zum Anhängen muß man die Datei entsprechend öffnen, damit sie nicht überschrieben wird:

Code: Alles auswählen

import numpy as np

vT = np.full((2,3), np.nan)
vT[1, 0] = 1
vT[0, 1] = 2

with open("Hey.txt", 'a') as doc:
    np.savetxt(doc, vT, delimiter='\t')
ConanDerBarbar
User
Beiträge: 19
Registriert: Donnerstag 21. März 2019, 00:52

@Sirius3 Das löst auf jeden Fall schonmal mein Problem mit dem Anhängen. Danke!



Ich habe den Code auf 3 unterschiedlichen Rechnern ausprobiert. Linux und Windows und jedes Mal wird es mir nur in einer Zeile in die Texdatei geschrieben. Könnte man das Problem mit fmt lösen?
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@ConanDerBarbar: es gibt kein Problem, das es zu lösen gibt. Woran merkst Du, dass alles in eine Zeile geschrieben wird?
ConanDerBarbar
User
Beiträge: 19
Registriert: Donnerstag 21. März 2019, 00:52

@Sirius3 Daran dass die Ausgabe in der Texdatei in einer Zeile ist. egal ob delimiter und newline gesetzt sind oder nicht. Also die Ausgabe ist genau wie in meinem zweiten Codebeispiel.


Habe gerade deinen Code ausprobiert und jetzte sagte er mir: TypeError: Mismatch between array dtype ('float64') and format specifier ('%1.4f %1.4f %1.4f')

Bin gerade am rumprobieren, wie ich das mit dem fmt lösen kann.
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@ConanDerBarbar: Du mußt den fmt für eine Zahl angeben '%1.4f'

Da das mit der einen Zeile nicht sein kann, versuche ich gerade herauszufinden, wie Du denn das festgestellt hast. Was liefert denn

Code: Alles auswählen

with open('HEY.txt', 'rb') as data:
    print(data.read())
Benutzeravatar
__blackjack__
User
Beiträge: 13112
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@ConanDerBarbar: Das was Du „Properties“ nennst sind Argumente der Funktion. Properties sind etwas anderes: https://docs.python.org/3.6/library/fun ... l#property

Wenn ich das Beispiel von Sirius3 laufen lasse, bekomme ich eine Datei mit zwei Zeilen:

Code: Alles auswählen

$ cat Hey.txt
nan	2.000000000000000000e+00	nan
1.000000000000000000e+00	nan	nan
$ wc --lines Hey.txt 
2 Hey.txt
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
ConanDerBarbar
User
Beiträge: 19
Registriert: Donnerstag 21. März 2019, 00:52

@Sirius3

Dann Spuckt mir Python b'' aus.

@__blackjack__ Ich scheine aus irgendeinem Grund immer Prameter mit Property überall gedanklich ersetzt zu haben... Irgendwie ist mir das nie aufgefallen. In einigen Dingen bin ich echt verpeilt..

Ich habe das Beispiel auch 1:1 kopiert, bekomme aber diese Fehlermeldung: TypeError: Mismatch between array dtype ('float64') and format specifier ('%1.4f %1.4f %1.4f')

Ich bin total ratlos...
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Wenn Du b'' ausgegeben bekommst, dann ist Deine Datei leer. Angeblich soll aber eine Zeile drin stehen.

Welches Beispiel?
Ein Beispiel, das eigentlich Dein gewünschtes Ergebnis liefern sollte:

Code: Alles auswählen

import numpy as np

vT = np.full((2,3), np.nan)
vT[1, 0] = 1
vT[0, 1] = 2

with open("Hey.txt", 'a') as doc:
    np.savetxt(doc, vT, delimiter='\t', fmt='%1.4f')

with open('Hey.txt', 'rb') as data:
    print(data.read())
Was ist hier die Ausgabe?
ConanDerBarbar
User
Beiträge: 19
Registriert: Donnerstag 21. März 2019, 00:52

@Sirius 3. Entschuldigung. Das die Datei leer ist, ist mein Fehler. Ich hab den Inhalt vor jeder Programmveränderung immer händisch gelöscht und wegen des Fehlers der mir ausgespuckt wurde, wurde ja nichts in die Datei reingeschrieben. Wenn ich jetzt nochmal zu dem Programm zurückgehe, welches mir die eine Zeile reinschreibt kommt folgendes raus: b'nan\t2.799999999999999822e+00\tnan\n1.100000000000000089e+00\tnan\tnan\n'

Die Ausgabe in die Texdatei sieht so aus: nan 2.799999999999999822e+00 nan1.100000000000000089e+00 nan nan

Da wo der Zeilenumbruch sein müsste, sind nan und 1,1 direkt aneinander.



Bei diesem Beispiel bekomme ich die Fhelermeldung:

Code: Alles auswählen

import numpy as np

vT = np.full((2,3), np.nan)
vT[1, 0] = 1
vT[0, 1] = 2

with open("Hey.txt", 'a') as doc:
    np.savetxt(doc, vT, delimiter='\t')
    

Wenn ich folgenden Code laufen lasse:

Code: Alles auswählen

import numpy as np

vT = np.full((2,3), np.nan)
vT[1, 0] = 1
vT[0, 1] = 2

with open("Hey.txt", 'a') as doc:
    np.savetxt(doc, vT, delimiter='\t', fmt='%1.4f')

with open('Hey.txt', 'rb') as data:
    print(data.read())
    
bekomme ich erneut folgende Fehlermeldung: TypeError: Mismatch between array dtype ('float64') and format specifier ('%1.4f %1.4f %1.4f')
Benutzeravatar
__blackjack__
User
Beiträge: 13112
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@ConanDerBarbar: Wie man sieht sind in der Datei eindeutig zwei Zeilenendezeichen. Also bleibt die Frage wie *Du* das überprüfst. Etwa Notepad? Dann ist *das* das Problem. Nimm einen vernünftigen Editor.

Bei mir läuft das Programm von Sirius3 problemlos durch und liefert folgende Ausgabe:

Code: Alles auswählen

b'nan\t2.0000\tnan\n1.0000\tnan\tnan\n'
Also genau das was man erwarten würde.

Selbst wenn ich den `dtype` beim erstellen von `vT` explizit als `np.float64` angebe, bekomme ich nicht die Fehlermeldung. Kannst Du davon mal bitte den kompletten Traceback zeigen und nicht nur die letzte Zeile?
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
ConanDerBarbar
User
Beiträge: 19
Registriert: Donnerstag 21. März 2019, 00:52

@__blackjack__ ich verwende kein Notepad. Um das Programm zu schreiben verwende ich Spyder und um mir die Texdatei anzusehen, einfach den Windows-integrierten Editor.

Der Traceback für folgendes Programm:

Code: Alles auswählen

import numpy as np

vT = np.full((2,3), np.nan)
vT[1, 0] = 1
vT[0, 1] = 2

with open("Hey.txt", 'a') as doc:
    np.savetxt(doc, vT, delimiter='\t', fmt='%1.4f')

with open('Hey.txt', 'rb') as data:
    print(data.read())
    
sieht wie folgt aus:

Code: Alles auswählen

Traceback (most recent call last):

  File "<ipython-input-40-9af716c21d41>", line 1, in <module>
    runfile('C:/Users/canan/Desktop/untitled0.py', wdir='C:/Users/canan/Desktop')

  File "C:\Users\canan\Desktop\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\spyder\utils\site\sitecustomize.py", line 880, in runfile
    execfile(filename, namespace)

  File "C:\Users\canan\Desktop\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\spyder\utils\site\sitecustomize.py", line 102, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "C:/Users/canan/Desktop/untitled0.py", line 15, in <module>
    np.savetxt(doc, vT, delimiter='\t', fmt='%1.4f')

  File "C:\Users\canan\Desktop\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\numpy\lib\npyio.py", line 1162, in savetxt
    % (str(X.dtype), format))

TypeError: Mismatch between array dtype ('float64') and format specifier ('%1.4f	%1.4f	%1.4f')
Für folgendes Programm:

Code: Alles auswählen

import numpy as np

vT = np.full((2,3), np.nan)

vT[1, 0] = 1.1
vT[0, 1] = 2.8

with open ("Hey.txt", 'a') as doc:
    np.savetxt(doc, vT, delimiter = '\t', newline = '\n')
    
ist der Traceback:

Code: Alles auswählen

Traceback (most recent call last):

  File "<ipython-input-41-9af716c21d41>", line 1, in <module>
    runfile('C:/Users/canan/Desktop/untitled0.py', wdir='C:/Users/canan/Desktop')

  File "C:\Users\canan\Desktop\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\spyder\utils\site\sitecustomize.py", line 880, in runfile
    execfile(filename, namespace)

  File "C:\Users\canan\Desktop\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\spyder\utils\site\sitecustomize.py", line 102, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "C:/Users/canan/Desktop/untitled0.py", line 37, in <module>
    np.savetxt(doc, vT, delimiter = '\t', newline = '\n')

  File "C:\Users\canan\Desktop\WinPython-64bit-3.5.3.1Qt5\python-3.5.3.amd64\lib\site-packages\numpy\lib\npyio.py", line 1162, in savetxt
    % (str(X.dtype), format))

TypeError: Mismatch between array dtype ('float64') and format specifier ('%.18e	%.18e	%.18e')
Ich habe jetzt das fmt rausgenommen bei dem zweiten Programm, mit dem ich davor rumexperimentiert habe, weshalb der Fehler jetzt einen anderen format specifier hat.


Ich danke euch beiden schonmal für eure Hilfe bis jetzt!
__deets__
User
Beiträge: 14542
Registriert: Mittwoch 14. Oktober 2015, 14:29

Fuer mich funktioniert dein zweites Programm so wie gezeigt ohne Fehler und produziert den erwarteteten Output. Das ist allerdings unter Linux. *Sollte* aber keinen Unterschied machen.
Antworten