Guten Tag,
ich habe folgendes Problem. Ich habe eine Datei mit 50.000 Zeilen wo mehrer Stufen eines Experiments abgebildet sind mit unterschiedlichen Spaltenanzahlen und Spaltenüberschrift. Die Spaltenüberschrift ist zweizeilig und lässt sich von mir mittels einer YAML Konfiguration auf einen neuen Namen zuweisen, mittels welchen ich dann später meine Auswertung betreiben möchte. Da ich ein größeres Projekt gestalte, arbeite ich mit Klassen.
Nun habe ich das Problem dass die Messwerte sowie Spaltentrennung dasselbe Zeichen verwendet. Anstelle 0.0 , 1.375 , 50, 0.00008 .... steht bei mir 0,0,1,375,50,0,00008. Die Originaldatei ist eine CSV und sämtliche Unicode Einstellungen können das Problem nicht beheben, selbiges mit der Auswahl des Trennzeichens. Auch das Umwandeln der Daten in eine txt Datei ändert das Problem nicht. Zwischenzeitlich habe ich auch für kleinere Kommastellen ein entsprechendes e für die Nachkommastellen, dass auch nicht erkannt wird :
81,92,3,039,0,170923,128,038,29,97,749,79,0,896916,0,91673,0,96375665,0,0366124,3,20,16,00,0,00,0,00,0,001,0,01,0,20,7,58642e-6,3,009180e-5,3,855498,3,85532,200,00,0,00000,1,18,9,77570e-4
jedes ungerade Komma sollte dabei ein '.' sein, jedes zweite Komma sollte ein ',' bleiben und die e in ein float verwandelt werden also wie hier:
81.92,3.039,0.170923,128.038,29.97,......
Meine Frage ist nun wie ich die Werte so aufbereiten kann dass ich sie auswerten kann, ohne meine Konfiguration neu aufsetzen zu müssen? Mit Regex hatte ich derweil auch noch keinen Erfolg.
Falsche Trennzeichen in Textdatei
Woher hast Du die Daten? Es ist nur die zweit beste Lösung, im Nachhinein kaputte Daten zu reparieren, wenn man sie auch gleich richtig schreiben könnte.
Ein regulärer Ausdruck würde so aussehen:
Ein regulärer Ausdruck würde so aussehen:
Code: Alles auswählen
re.sub("(\d+),(\d+(?:e[+-]?\d+)?,|$)", lambda m: f"{m.group(1)}.{m.group(2)}", line)Richtig wäre, die CSV so schreiben zu lassen, dass sie sich an die CSV-Spezifikation hält, und eindeutig lesbar ist.
Also entweder direkt ein Semikolon als Trenner zwischen den Zahlen, oder die Zahlen in Anführungszeichen setzen, usw.
Das nachträglich zu reparieren scheint mir aufwändiger und fehleranfälliger.
Haben bspw. wirklich alle Zahlen ein Dezimalkomma? In deinem Beisiel stand ja auch 50 und nicht 50,0
Also entweder direkt ein Semikolon als Trenner zwischen den Zahlen, oder die Zahlen in Anführungszeichen setzen, usw.
Das nachträglich zu reparieren scheint mir aufwändiger und fehleranfälliger.
Haben bspw. wirklich alle Zahlen ein Dezimalkomma? In deinem Beisiel stand ja auch 50 und nicht 50,0
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
- DeaD_EyE
- User
- Beiträge: 1373
- Registriert: Sonntag 19. September 2010, 13:45
- Wohnort: Hagen
- Kontaktdaten:
Man hat nicht immer die Kontrolle über die Quelle, also muss man um das Problem drumherum arbeiten.
Wenn man die Daten so selbst produziert hat, sollte man das richtig stellen, um zukünftige Probleme zu vermeiden.
Hier ein Ansatz ohne regex. Ich vermute mal, dass die Regex-Variante schneller ist. Habs nicht gemessen.
Falls die CSV einen Header hat, sollte schon die erste Zeile einen Fehler ausgeben. Er macht aber weiter bis zum Ende.
Wenn man die Daten so selbst produziert hat, sollte man das richtig stellen, um zukünftige Probleme zu vermeiden.
Hier ein Ansatz ohne regex. Ich vermute mal, dass die Regex-Variante schneller ist. Habs nicht gemessen.
Code: Alles auswählen
import itertools
def fix_floats(lines):
for line_no, line in enumerate(lines, 1):
floats = []
try:
for a, b in itertools.batched(line.split(","), n=2):
floats.append(float(f"{a}.{b}"))
except ValueError:
print(f"Fehler in Zeile {line_no}: {line}")
continue
yield floats
lines = [
"81,92,3,039,0,170923,128,038,29,97,749,79,0,896916,0,91673,0,96375665,0,0366124,3,20,16,00,0,00,0,00,0,001,0,01,0,20,7,58642e-6,3,009180e-5,3,855498,3,85532,200,00,0,00000,1,18,9,77570e-4, 5,5",
"1,2,3,4",
"a b c",
"1,2,3",
]
for floats in fix_floats(lines):
print(floats)
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
@meli99: Nur um das noch einmal herauszustellen: Dein Beispiel zeigt, dass deine Lösung nicht funktioniert und das fehlerhafte Trennzeichen dazu führt, dass deine Werte (zumindest teilweise) unbrauchbar sind. Wenn sich an dem Ursprungsformat nichts machen lässt, sehe ich da gar keine Chance. Das Problem hat Kebap korrekt erkannt und benannt.
Wenn das:
Wenn das:
tatsächlich so ist, kannst du nicht jedes zweite Komma ersetzen. Denn dann ergäbe 0.0,1.375,50.0,00008. Und das sind nicht die Originaldaten.meli99 hat geschrieben: Dienstag 11. August 2026, 22:260.0 , 1.375 , 50, 0.00008 .... steht bei mir 0,0,1,375,50,0,00008
