Einzelne Zeilen in txt datei loeschen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
phygirl
User
Beiträge: 16
Registriert: Sonntag 23. August 2009, 12:01

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
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

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.
phygirl
User
Beiträge: 16
Registriert: Sonntag 23. August 2009, 12:01

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()
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

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.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

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 ;-).
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

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
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

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.
dahaze
User
Beiträge: 75
Registriert: Freitag 13. März 2009, 10:57
Wohnort: im Schwabenland

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:
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

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.
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

dahaze: Mit solchen Code-Beispielen tust du Niemanden einen Gefallen.
Bottle: Micro Web Framework + Development Blog
BlackJack

Vor allem funktioniert das auch gar nicht. Da wird für jede Zeile immer wieder die gleiche Ausgabedatei geöffnet und überschrieben. :roll:
dahaze
User
Beiträge: 75
Registriert: Freitag 13. März 2009, 10:57
Wohnort: im Schwabenland

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()])
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

@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
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

@CM: Du kannst doch trotzdem über die ganze Datei iterieren, die Zeile sollte halt einfach ignoriert werden.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

@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.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

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.
Antworten