Seite 1 von 1

Einzelne Zeilen in txt datei loeschen

Verfasst: Mittwoch 16. Dezember 2009, 09:46
von phygirl
Hallo,

ich habe das Problem das ich in Python eine ganze Menge an Dateien plotten moechte (mit matplotlib). Die ganzen ascii-Daten fangen aber alle mit 3 Zeilen text an und hoehren mit unterstrichen auf also:


dateinamte.txt
xachse yachse zachse
------------------------------
1 2 3
1 2 3
------------------------------


Um das nun zu plotten muss ich die Textzeilen immer per hand loeschen oder auskommentieren. Kennt jemand vielleicht ien Moeglichkeit, wie ich Python vor dem plotten sage, was er ignorieren/loeschen soll?

Danke im vorraus

Verfasst: Mittwoch 16. Dezember 2009, 09:52
von Hyperion
Naja, Du parst die Eingabedatei und übergibst die bereinigte Struktur an matplotlib. Zu diesem Thema gab es schon zig Anfragen, in denen Vorgehensweisen aufgezeigt wurden.

Stichwörter für die Suche könnten sein: Dateien parsen, Textdatei splitten, u.ä.

Ansonsten: Einfach mal die ersten zwei, drei Seiten durchstöbern, da ist auf jeden Fall noch was zu finden.

Verfasst: Mittwoch 16. Dezember 2009, 10:18
von phygirl
Ich habe das jetzt durch rausschreiben in eine neue Datei geloest, aber ich weiss nicht wie ich ihm sage, dass er die letze Zeile loeschen soll, vorallem da alle Datein unterschiedlich lang sind...


Code: Alles auswählen

fin = open( 'test.dat', "r" )
data_list = fin.readlines()
fin.close()

del data_list[0:2]

fout = open("test2.dat", "w")
fout.writelines(data_list)
fout.close()

Verfasst: Mittwoch 16. Dezember 2009, 10:24
von Hyperion
1.) Ist es beabsichtigt, die Dateien wirklich zu ändern, oder sollen die Daten nicht direkt an matplotlib übergeben werden?

2.) Du solltest Dir mal das idiomatische Vorgehen für das Öffnen von Dateien angucken. Bei Dir fehlt ja sämtliche Fehlerbehandlung...

3.) Du verwendest doch eh schon Slicing - da sollte das doch kein Problem darstellen ;-) Zur Not guck halt noch einmal ins Tutorial.

Verfasst: Mittwoch 16. Dezember 2009, 10:32
von CM
phygirl hat geschrieben:

Code: Alles auswählen

data_list = fin.readlines()
Das ist überhaupt keine gute Idee, wenn Du wirklich viele Daten hast.

Code: Alles auswählen

def simplyparse(fname, ...):
    with open(fname) as infile:
        for line in infile:
            if line[0].isdigit():
                coords = imap(float, line.split())
...
Ok, bei wirklich vielen Daten ist das if-statement eher unschön. Da ist jetzt Deine Kreativität gefragt.

Wenn Du Einfluß auf das Datenformat hast: Ändern. ;-) numpy.loadtxt gibt Dir dann z. B. die Möglichkeit Headerzeilen zu überspringen und Du hast gleich schöne np-arrays. :D

HTH
Christian

edit / PS Ok, Fehlerbehandlung wäre u. U. hier auch noch eine tolle Sache ... Bevor ich geschlagen werde ;-).

Verfasst: Mittwoch 16. Dezember 2009, 10:57
von sma
Noch ein Vorschlag:

Code: Alles auswählen

import re

def delete_lines(infile, outfile, matchf):
	for line in infile:
		if matchf(line):
			continue
		outfile.write(line)

with open("in.txt") as infile:
	with open("out.txt") as outfile:
		delete_lines(infile, outfile, lambda line: re.match("^-+$", line))
Stefan

Verfasst: Mittwoch 16. Dezember 2009, 11:03
von Hyperion
sma hat geschrieben:Noch ein Vorschlag:

Code: Alles auswählen

import re

def delete_lines(infile, outfile, matchf):
	for line in infile:
		if matchf(line):
			continue
		outfile.write(line)

with open("in.txt") as infile:
	with open("out.txt") as outfile:
		delete_lines(infile, outfile, lambda line: re.match("^-+$", line))
Stefan
Nett :-) Das Filtering per lambda ist hier recht hübsch - Wobei es so noch nicht ganz hinhaut, da ja wohl auch der Text entfernt werden soll.

Verfasst: Donnerstag 17. Dezember 2009, 15:46
von dahaze
Oder das ganze in einer Zeile:

Code: Alles auswählen

[open('testout.txt','w').writelines(line) for line in open('testin.txt','r').readlines() if line[0].isdigit()]
Wie das laufzeittechnisch ist, kann ich leider nicht beurteilen....das überlass ich euch... :roll:

Verfasst: Donnerstag 17. Dezember 2009, 19:23
von derdon
Erstens kannst du dir das ``….readlines()`` sparen und zweitens wird nicht sichergestellt, dass die Dateien auch geschlossen werden. Vor allem letzteres ist wichtiger als die Ausführungsgeschwindigkeit des codes.

Verfasst: Donnerstag 17. Dezember 2009, 19:27
von Defnull
dahaze: Mit solchen Code-Beispielen tust du Niemanden einen Gefallen.

Verfasst: Donnerstag 17. Dezember 2009, 21:00
von BlackJack
Vor allem funktioniert das auch gar nicht. Da wird für jede Zeile immer wieder die gleiche Ausgabedatei geöffnet und überschrieben. :roll:

Verfasst: Freitag 18. Dezember 2009, 08:40
von dahaze
derdon:
Wenn ich mir das readlines() sparen würde, hätte ich allerdings alle Zahlen in einer Zeile. Denke so war das nicht gedacht?
Dass die Dateien nicht explizit geschlossen werden finde ich allerdings nicht weiter schlimm da der Garbagecollector sie danach wieder abräumt. Ich binde diese ja nicht an irgendwelche Variablen. Oder darf man sich darauf nicht verlassen?

sma:
Aber ihr vielleicht mir wenn ihr mir sagt was daran schlecht ist?

BlackJack:
Stimmt....das ist mir leider entgangen.
In diesem Fall wäre es dann so besser?

Code: Alles auswählen

open('testout.txt','w').writelines([line for line in open('testin.txt','r').readlines() if line[0].isdigit()])

Verfasst: Freitag 18. Dezember 2009, 10:27
von CM
@dahaze: Wozu das readlines? Wozu die LC? Und warum ein Konstrukt, dass es immer noch nicht erlaubt Fehler zu behandeln oder Dateien zu schliessen? ;-)
Und - mal überlegen: Ich habe z. B. ca. 4 GB Hauptspeicher. Was passiert wenn die Datei größer als 4 GB - Platzbedarf OS - Platzbedarf offene Programme ist? Im besten Fall: Ziemlich lange Däumchendrehen ;-). (Wir erinnern uns: Die Dateien sind groß - wenn wir auch nicht wissen wie groß.)

Was mich wirklich stört ist die letzte Zeile in der Datei: Ohne diese Zeile gäbe es elegante Lösungen ohne zusätzliche Funktionsaufrufe, tmp-Files, etc.. Einfach schön über die Datei iterieren und das möglichst speicherschonend. Es gibt keine Möglichkeit diesen Punkt zu ändern?

Gruß,
Christian

Verfasst: Freitag 18. Dezember 2009, 10:41
von mkesper
@CM: Du kannst doch trotzdem über die ganze Datei iterieren, die Zeile sollte halt einfach ignoriert werden.

Verfasst: Freitag 18. Dezember 2009, 11:33
von cofi
@dahaze: Nein, du kannst dich nicht darauf verlassen, da der GC dann anspringt, wenn er es fuer richtig haelt und nicht jedes Mal, wenn etwas aufzuraeumen ist. Wenn man plant mit der Datei zeitnah etwas anzufangen, ist das eine schlechte Idee.
Du hast im Uebrigen immer noch das Speicherproblem. Genauer gesagt brauchst du sogar doppelten Speicher.
`writelines` schreibt uebrigens keine `\n`, darum muss man sich darum selbst kuemmern, `writelines` ist nichts anderes als ein `write` das eine Sequenz entgegennimmt.

Verfasst: Freitag 18. Dezember 2009, 11:40
von CM
mkesper hat geschrieben:die Zeile sollte halt einfach ignoriert werden.
Aber genau dazu braucht es entweder ein try/except oder pro Zeile einen Funktionsaufruf. Was ich meinte ist, schön wäre es "umstandslos" iterieren zu dürfen ...

Aber andererseits kann das nicht so sehr ins Gewicht fallen können: Man wird die Spalten ohnehin zu Zahlen konvertieren müssen. Da fällt ein .isdigit() oder eine regex wohl nicht so sehr auf.