bestimmte Zeilen einer ASCII Datei Löschen

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.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@zimmernagel: die Größe der Datei ist nebensächlich, und die Geschwindigkeit hauptsächlich abhängig von der Geschwindigkeit Deiner Festplatte.
Das könnte ungefähr so aussehen:

Code: Alles auswählen

with open(input_filename) as points_in:
    with open(output_filename, 'w') as points_out:
        for line in points_in:
            point = map(float, line.split())
            if left_border <= point[0] <= right_border and top_border <= point[1] <= bottom_border:
                points_out.write(line)
Benutzeravatar
zimmernagel
User
Beiträge: 24
Registriert: Dienstag 9. Dezember 2014, 13:22
Wohnort: Bitburg

Ja, ok, fein, danke! Das ist die Hauptaufgabe des Programmes!

Das ist schon die halbe Miete. Ich hab' jetzt noch mit "file split" die Dateien auf 64mb aufgesplittet bekommen, damit man beim testen nicht so lange warten müsste...

...aber wie sage ich jetzt dem programm, wo die Datei steht, bzw. wo er hinschreiben will? Ich weiss, das ist Standardkram, aber ich hab erst von python erfahren, wo ich mal "Finale" - Musikprogramm installiert habe... - oder war's capella? ;-)

Ich muss dem Programm sagen (z.b. im Format 326000,5536000 (unten-links) und 328000,5538000 (für oben links)) was er als Begrenzung holt für "point[0]" und "point[1]"

Mir würde ja schon reichen, wenn ich das im programm ändern kann...

Fragen über Fragen, als Newbie einer völlig fremden "Sache" ist man erstmal "aufgeschmissen" - erst bei einem praktischen Vorentwurf, dass in die gleiche Richtung des eigenen Problems geht, hat man die magischen "Aha-Erlebnisse"

Vielen Dank für das "Hauptprogramm" :-)
Benutzeravatar
zimmernagel
User
Beiträge: 24
Registriert: Dienstag 9. Dezember 2014, 13:22
Wohnort: Bitburg

Ok, habe das jetzt schonmal bisschen geändert:

Code: Alles auswählen

input_filename='c:\DGM\BitLand\DGMSPLIT\s.0'
output_filename='c:\DGM\BitLand\Output.xyz'
    with open(input_filename) as points_in:
        with open(output_filename, 'w') as points_out:
            for line in points_in:
                point = map(float, line.split())
                if left_border <= point[0] <= right_border and top_border <= point[1] <= bottom_border:
                    points_out.write(line)
Jetzt hängt er aber bei "with open...." mit der Fehlermeldung "unexpected indent"....!?!!?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Die Fehlermeldung sagt es ja schon: Unerwartete Einrückung. In Python ist die Einrückung Teil der Syntax, da darfst du nicht einfach so einrücken. In deinem Fall ist das Problem die Zeile 3, da darf keine Einrückung stehen.
Das Leben ist wie ein Tennisball.
Benutzeravatar
zimmernagel
User
Beiträge: 24
Registriert: Dienstag 9. Dezember 2014, 13:22
Wohnort: Bitburg

Das Leben ist wie ein Tennisball, mal auf mal ab..., joo, stimmt! ;-)

Ok, linker Rand mal "optimiert", jetzt kommt natürlich die Fehlermeldung mit dem "linken-Rand"...

Wie muss ich diese Gruppe eingeben, bzw. die Koordinaten?

Unten links, soll z.b. X=326000, Y=5536000 sein, oben links X=328000, Y=5538000 sein...

Code: Alles auswählen

left_border=326000,5536000
???
losgehts
User
Beiträge: 19
Registriert: Montag 8. Juni 2009, 01:00

Hallo,
Wie muss ich diese Gruppe eingeben, bzw. die Koordinaten?
Also, das würde ich für die ersten Tests ja erst einmal direkt in den Code schreiben:

Code: Alles auswählen

left_border = 326000
bottom_border = 5536000
right_border = 328000
top_border = 5538000
Und dann scheint mir in dieser Codezeile noch ein kleiner Logikfehler:
if left_border <= point[0] <= right_border and top_border <= point[1] <= bottom_border:

Grüße, Ulrich
Benutzeravatar
zimmernagel
User
Beiträge: 24
Registriert: Dienstag 9. Dezember 2014, 13:22
Wohnort: Bitburg

Ok, also, ich hab das jetzt mal "SO" geändert:

Code: Alles auswählen

input_filename='c:\DGM\BitLand\DGM5_RP.xyz'
output_filename='c:\DGM\BitLand\Output.xyz'
left_border = 326000
bottom_border = 5536000
right_border = 328000
top_border = 5538000
with open(input_filename) as points_in:
    with open(output_filename, 'w') as points_out:
        for line in points_in:
            point = map(float, line.split())
            if left_border <= point[0] <= right_border and top_border <= point[1] <= bottom_border:
                points_out.write(line)
Leider kommt da eine für mich ziemliche kryptische Fehlermeldung:
Traceback (most recent call last):
File "C:\Users\arwed.fraenken\Desktop\dgm.py", line 11, in <module>
if left_border <= point[0] <= right_border and top_border <= point[1] <= bottom_border:
TypeError: 'map' object is not subscriptable
Da scheint wohl irgendwas mit den Daten in der Zeile nicht richtig zu sein. Muss ich die Zeile nicht irgendwie auf die obigen "border"-Grenzen temporär auf Variablen setzen und direkt vergleichen? Wenn ich z.b. die Zeilen nochmal zeige:

308000.000 5526000.000 314.916
308005.000 5526000.000 317.069
308010.000 5526000.000 319.278

Dann ist die 308000 zu vergleichen mit "left_border" - wenn die dann kleiner ist wie "left_border", dann kann die Zeile ja schon direkt "vergessen" werden.
Wenn der zweite Wert in der Zeile - 5526000 ist bzw. kleiner als der "bottom_border", dann kann die Zeile auch vergessen werden.
Wenn der erste Wert in der Zeile - 308000 größer wie der "right_border", dann kann die Zeile auch vergessen werden.
Wenn der zweite Wert in der Zeile - 5526000 größer wie der "top_border", dann kann die Zeile auch vergessen werden.

Aber die 2 ersten Werte (308000 und 5526000) in der Zeile müssten doch irgendwie gezielt als Variable markiert/aufgeschlüsselt werden, um diese in der if-klause zu erkennen und dann zu bearbeiten...?
Die z-Koordinate kann komplett wegfallen - in Sachen Bearbeitung!

Achherje...
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

zimmernagel hat geschrieben:Da scheint wohl irgendwas mit den Daten in der Zeile nicht richtig zu sein. Muss ich die Zeile nicht irgendwie auf die obigen "border"-Grenzen temporär auf Variablen setzen und direkt vergleichen? Wenn ich z.b. die Zeilen nochmal zeige:
Nö, du hast nur Code blind übernommen, dessen Funktionsweise du nicht verstehst ;-) Deine Python-Version liefert beim map-Aufruf einen Generator, darauf kannst du nicht über einen Index zugreifen (das sagt die Fehlermeldung). Um das zu lösen, könntest du aus dem Ergebnis des map-Aufrufst ein Tupel oder eine Liste machen.
Das Leben ist wie ein Tennisball.
Benutzeravatar
zimmernagel
User
Beiträge: 24
Registriert: Dienstag 9. Dezember 2014, 13:22
Wohnort: Bitburg

Ok, *Tupelnachschlag*.... :-)
Benutzeravatar
zimmernagel
User
Beiträge: 24
Registriert: Dienstag 9. Dezember 2014, 13:22
Wohnort: Bitburg

*UFF*

Hab jetzt das mal mit Tupel gemacht, aber irgendwie vergleiche ich wohl immer noch Äpfel mit Birnen...

Code: Alles auswählen

input_filename='c:\DGM\BitLand\DGM5_RP.xyz'
output_filename='c:\DGM\BitLand\Output.xyz'
left_border = 326000
bottom_border = 5536000
right_border = 328000
top_border = 5538000
with open(input_filename) as points_in:
    with open(output_filename, 'w') as points_out:
        for line in points_in:
            point = map(float, line.split())
            tuple = line.split()
            wert_x = tuple[0]
            wert_y = tuple[1]            
            if left_border >= wert_x  <= right_border and bottom_border >= wert_y <= top_border:
                points_out.write(line)
Die Fehlermeldung dazu:
Traceback (most recent call last):
File "C:\Users\arwed.fraenken\Desktop\dgm.py", line 14, in <module>
if left_border >= wert_x <= right_border and bottom_border >= wert_y <= top_border:
TypeError: unorderable types: int() >= str()
Ich bin mit meinem nichtvorhandenen Latein am Ende...

Die dazugehörigen Daten aus der Shell:
>>> wert_x
'308000.000'
>>> wert_y
'5526000.000'
>>> line
'308000.000 5526000.000 314.916\n'
>>> tuple
['308000.000', '5526000.000', '314.916']
>>>
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

So funktioniert Programmieren nicht, du kannst nicht einfach versuchen eine Lösung zu raten. Der map-Aufruf hat ja eine gewisse Funktion, der wurde nicht einfach so geschrieben. Daher kannst du ihn auch nicht einfach ignorieren. Lies doch meinen letzten Beitrag durch, da steht drin was du machen musst.
Das Leben ist wie ein Tennisball.
Benutzeravatar
zimmernagel
User
Beiträge: 24
Registriert: Dienstag 9. Dezember 2014, 13:22
Wohnort: Bitburg

Ja, ok, so funktioniert es nicht - aber ist es nicht so, dass man(n) bzw. ich früher bei AutoCAD LISP viel rumprobiert habe und mir die Variablen angezeigt habe, und erst verstanden habe, bis es mal funktioniert hatte - dann hat's bei mir erst *klick* gemacht. Man lernt ja nicht Autofahren, indem man nur die Bögen richtig ankreuzt...
Wenn ich mir die Tutorials durchforste, seh ich jetzt trotzdem bei mir nicht den Fehler mit dem "MAP"..., da fehlen mir einfach die Grundkenntnisse - um jetzt schnell an's Ziel zu kommen..., leider...
Benutzeravatar
zimmernagel
User
Beiträge: 24
Registriert: Dienstag 9. Dezember 2014, 13:22
Wohnort: Bitburg

Hab das alles nochmal durchgeschaut und das jetzt mal mit einer Liste probiert. Er läuft erstaunlicherweise ziemlich schnell durch die 1.2 GB-Datei, so gefühlte 40 sec. - allerdings bleibt die Datei leer, wird zwar angelegt, bleibt aber leer...

Code: Alles auswählen

input_filename='c:\DGM\BitLand\DGM5_RP.xyz'
output_filename='c:\DGM\BitLand\Output.xyz'
left_border = 320000.000
bottom_border = 5556800.000
right_border = 321000.000
top_border = 5556900.000
with open(input_filename) as points_in:
    with open(output_filename, 'w') as points_out:
        for line in points_in:
            point = list(map(float, line.split()))
            wert_x = point[0]
            wert_y = point[1]
            if left_border >= wert_x  and right_border <= wert_x and bottom_border >= wert_y and  top_border <= wert_y:
                points_out.write(line)
BlackJack

@zimmernagel: Dann erfüllt offensichtlich keine Zeile die Bedingungen. Erstell eine Datei mit ein oder zwei Einträgen die Deiner Meinung nach die Bedingungen erfüllen müssten und prüfe dann wo Deine Erwartungen an das Programm von der Wirklichkeit abweicht.
Benutzeravatar
zimmernagel
User
Beiträge: 24
Registriert: Dienstag 9. Dezember 2014, 13:22
Wohnort: Bitburg

mmh, ja, das habe ich bereits getestet, hab schon direkt die ersten Zeilen am Endpunkte geholt, die Datei bleibt leer...
BlackJack

@zimmernagel: Na dann musst Du jetzt herausfinden warum das so ist. Probier die einzelnen Teilausdrücke doch einfach mal in einer Python-Shell aus und vergleiche das Ergebnis mit dem was Du erwartest. Irgendwo muss dann ja ein Unterschied auftreten.
Benutzeravatar
zimmernagel
User
Beiträge: 24
Registriert: Dienstag 9. Dezember 2014, 13:22
Wohnort: Bitburg

ja, die Möglichkeit muss ich jetzt noch ausschöpfen, und das schritt für schritt mal abtesten...
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@zimmernagel: bei Dir scheinen Größer und Kleiner lustig herumzuwandern. Du weißt schon, was Vergleichsoperatoren sind?
Benutzeravatar
zimmernagel
User
Beiträge: 24
Registriert: Dienstag 9. Dezember 2014, 13:22
Wohnort: Bitburg

Jepp, nach Umtauschen der Größer/Kleiner Pfeile siehe da, da waren auch im Ausgang Daten da! ;-)

Geht jetzt - innerhalb 40 sec. eine Ortslage mit 5-7 MB-Datei von 1.2 GB - Python sei dank!

Vielen Dank für die Hilfen hier!
Benutzeravatar
zimmernagel
User
Beiträge: 24
Registriert: Dienstag 9. Dezember 2014, 13:22
Wohnort: Bitburg

Hallo zusammen!

Ist es vielleicht möglich, bei der Abfrage des Fensters auch andere Formen zu berücksichtigen? Also ich habe ja immer momentan ein Rechteck in den Ecken definiert. Manchmal wäre es aber gut, wenn man auch die Kanten schräg ziehen könnte. aber dann müsste er ja zeilenweise die Position der Kante selbst ausrechnen, damit er beurteilen kann, ob die momentan betroffene Zeile des DGM in oder ausserhalb der Kante liegt. Geht das mit Python???
Antworten