join() in eine neue Zeile

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
Kahnbein.Kai
User
Beiträge: 104
Registriert: Mittwoch 24. Juni 2015, 14:12
Wohnort: Bochum

Hallo,
ich brauche mal wieder die Hilfe des Forums.
Ich habe eine xyz Datei einer Punktwolke und möchte diese Sortieren, das heißt alle 2er Werte (der letzte Wert in einer Zeile) behalten, der Rest kann weg.
Ein Auszug aus der Datei:

Code: Alles auswählen

x;y;z;c
370866.86;5721834.73;66.47;58
370868.86;5721834.73;66.51;58
370870.86;5721834.73;66.61;58
370868.86;5721832.73;66.58;58
370870.86;5721832.73;66.65;58
370658.3;5721562.11;67.33;58
370658.3;5721560.11;67.37;58
370660.3;5721560.11;67.37;58
370660.3;5721558.11;67.45;58
370660.3;5721556.11;67.52;58
370662.3;5721556.11;67.54;2
370622.74;5721389.32;68.28;2
370622.74;5721387.32;68.25;2
370211.71;5721293.98;69.77;2
370211.71;5721291.98;69.74;2
370211.71;5721289.98;69.71000000000001;2
370213.71;5721289.98;69.74;2
370211.71;5721287.98;69.7;2
370278.03;5721626.3100000005;73.11;2
370278.03;5721644.16;74.12;2
Mein Script:

Code: Alles auswählen

with open ("Test.xyz", "r") as file, open("Test_B.xyz", "w") as out:        
            
    for line in range(1):
        next(file)
		
        for line in file:
        	x1 = line.find(";")
        	x2 = line.find(";",x1+1)
        	x3 = line.find(";",x2+1)
        	
        	if int(line[x3+1:])==2:
        	    print(line)
        	    y1 = round(float(line[0:x1-1]),3)
        	    y2 = round(float(line[x1+1:x2-1]),3)
        	    y3 = round(float(line[x2+1:x3-1]),3)

        	    
        	    list = []
        	    list.append(str(y1))
        	    list.append(str(y2))
        	    list.append(str(y3))
        	    
        	    print(list)

        	    sep = ';'
        	    line = sep.join(list)
        	    
        	    out.write(line)
        	    
Das Problem ist, das Join() mir alles in einer Zeile ausgibt, dabei sollten jeweils die drei Zahlen in einer Zeile stehen.
Ich weiß einfach nicht wohin das

Code: Alles auswählen

'\n’
kommt, um jeweils in eine neue Zeile zu schreiben.

Gruß Kai
Benutzeravatar
__blackjack__
User
Beiträge: 14053
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Kahnbein.Kai: Das Zeilenendezeichen gehört ans Ende einer Zeile. 🙂

Dein Code macht sehr komische Sachen.

Die äussere ``for``-Schleife wird genau *einmal* durchlaufen und der Wert von `line` wird nirgends verwendet. Damit ist das ein völlig sinnfreies Konstrukt was einfach nur den Leser unnötig beschäftigt, der sich überlegt was das soll.

Man nummeriert keine Namen. Das ist auch vollig unnötig umständlich mit `find()` und den Indexwerten. Zerlege die Zeile einfach am Trennzeichen und gut ist.

Eine leere Liste zu erstellen und in den nächsten drei Zeilen jeweils einen Wert per `append()` anzuhängen ist auch umständlich. Warum hast Du da nicht gleich eine Liste mit den drei Elementen hingeschrieben. Zudem haben wir hier auch wieder nummerierte Namen und dreimal den gleichen Ausdruck. Das sollten keine drei Namen sein, sondern eine Liste und eine Schleife.

Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python3


def main():
    separator = ";"
    with open("Test.xyz", "r") as in_file, open("Test_B.xyz", "w") as out_file:
        next(in_file)  # Skip header.
        for line in in_file:
            *coordinate, this_needs_a_better_name = map(
                float, line.split(separator)
            )
            if this_needs_a_better_name == 2:
                print(line, end="")
                out_file.write(
                    separator.join(f"{value:.3f}" for value in coordinate)
                    + "\n"
                )


if __name__ == "__main__":
    main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Kahnbein.Kai
User
Beiträge: 104
Registriert: Mittwoch 24. Juni 2015, 14:12
Wohnort: Bochum

Guten Morgen @__blackjack__

Vielen Dank für deine Antwort.
Dein Code sieht mal wieder viel besser aus als meiner. :( Das macht aber wohl die Übung.

Zum Code, die erste Schleife ist von einem Arbeitskollegen, er meinte das ist nötig um den Header in der Eingabetabelle zu überspringen.

Code: Alles auswählen

 for line in range(1):
        next(file)
Ich habe es einfach durch

Code: Alles auswählen

next(file)
ersetzt. Hast recht, sieht viel besser und einfacher aus.
Das war meine eigene Idee, ich dachte mit 'find()' lässt sich das gut Lösen :), dein 'split()' macht natürlich auch einen aufgeräumten Eindruck.
In den Eingangsdaten sind manchmal Werte drin, die zuviele Nachkommastellen haben. Ich wollte jeden Eintrag auf zwei Nachkommastellen runden. Klappt mit Round auch nicht so sauber. Im neuen Code habe ich das noch anders gelöst :).
Stimmt, man hätte die Liste auch sofort erstellen und mit Werten füllen können.
Die 'join()' Fuktion war ein Versuch die drei Einzelwerte wieder in eine Zeile zu bekommen.
Hier ist nochmal die Eingangsdatei:

Code: Alles auswählen

x;y;z;c
370866.86;5721834.73;66.47;58
370868.86;5721834.73;66.51;58
370870.86;5721834.73;66.61;58
370868.86;5721832.73;66.58;58
370870.86;5721832.73;66.65;58
370658.3;5721562.11;67.33;58
370658.3;5721560.11;67.37;58
370660.3;5721560.11;67.37;58
370660.3;5721558.11;67.45;58
370660.3;5721556.11;67.52;58
370662.3;5721556.11;67.54;58
370622.74;5721389.32;68.28;58
370622.74;5721387.32;68.25;58
370211.71;5721293.98;69.77;58
370211.71;5721291.98;69.74;58
370211.71;5721289.98;69.71000000000001;58
370213.71;5721289.98;69.74;58
370211.71;5721287.98;69.7;58
370278.03;5721626.3100000005;73.11;2
370278.03;5721644.16;74.12;2
370278.03;5721649.55;74.24;2
370278.03;5721699.65;74.98;2
370278.03;5721708.68;75.21000000000001;2
370278.03;5721711.51;75.22;2
370278.03;5721721.01;75.46000000000001;2
370278.03;5721729.19;75.66;2
370278.03;5721757.16;76.2;2
370278.03;5721791.8100000005;76.67;2
370278.03;5721853.52;78.57000000000001;2
370436.12;5721917.4;78.60000000000001;2
370436.12;5721942.41;79.22;2
370436.12;5721969.05;79.88;2
370436.12;5721990.46;80.18;2
370436.13;5721007.8;75.96000000000001;2
370436.13;5721008.24;75.96000000000001;2
370436.13;5721026.28;75.95;2
370436.13;5721031.9;75.95;2
370436.13;5721038.95;75.96000000000001;2
370436.13;5721047.59;75.8;2
Hier der Code:

Code: Alles auswählen

with open ("Test.xyz", "r") as file, open("Test_B.xyz", "w") as out:     
   
    out.write("x;y;z"+"\n")
    next(file)
		
    for line in file:
     	x1 = line.find(";")
     	x2 = line.find(";",x1+1)
     	x3 = line.find(";",x2+1)
     	if int(line[x3+1:])==2:
     		y1 = float(line[0:x1])
     		y2 = float(line[x1+1:x2])
     		y3 = float(line[x2+1:x3])
     		line = ("%8.2f;%8.2f;%4.2f" % (y1,y2,y3))
     		out.write(line+"\n")
und hier die Ausgabedatei:

Code: Alles auswählen

x;y;z
370278.03;5721626.31;73.11
370278.03;5721644.16;74.12
370278.03;5721649.55;74.24
370278.03;5721699.65;74.98
370278.03;5721708.68;75.21
370278.03;5721711.51;75.22
370278.03;5721721.01;75.46
370278.03;5721729.19;75.66
370278.03;5721757.16;76.20
370278.03;5721791.81;76.67
370278.03;5721853.52;78.57
370436.12;5721917.40;78.60
370436.12;5721942.41;79.22
370436.12;5721969.05;79.88
370436.12;5721990.46;80.18
370436.13;5721007.80;75.96
370436.13;5721008.24;75.96
370436.13;5721026.28;75.95
370436.13;5721031.90;75.95
370436.13;5721038.95;75.96
370436.13;5721047.59;75.80
Danke für

Code: Alles auswählen

+ "\n"
Daran bin ich fast verzweifelt.
Jetzt versuche ich es mal mit deinem Code.

Gruß und Danke
Kai
Benutzeravatar
snafu
User
Beiträge: 6870
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Mach es dir doch einfacher und nutze das externe pandas-Paket:

Code: Alles auswählen

import pandas as pd

df = pd.read_csv("input.csv", sep=";")
result = df[df.c == 2]
print(result)
result.to_csv("output.csv", sep=";")
Kahnbein.Kai
User
Beiträge: 104
Registriert: Mittwoch 24. Juni 2015, 14:12
Wohnort: Bochum

Das ist ja noch einfacher, Danke für den Hinweis snafu ! :)

Gruß Kai
Antworten