Aber hier geht es um ein zusätzliches Feature und ich bin daran interessiert, ob ihr Ideen zur Optimierung habt.
Das "neue" Feature hier ist, dass während dem Einlesen einzelne Zeilen der CSV-Datei ersetzt werden. Nach diversen Einlese versuchen, weiß ich, welche Zeilen "kaputt" sind. Diese ersetze ich während dem Einlesen. Das erspart es mir, an den gelieferten Rohdaten manuell herum editieren zu müssen.
Eine CSV Datei wird über mehrere Zwischenschritte eingelesen und am Ende in ein Pandas DataFrame verwandelt. Die Zwischenschritte dienen der Validierung (im Beispiel-Code nur rudimentär abgebildet). Ein weiterer Schritt ist eben auch, dass eine der Zeilen ersetzt wird. Zeile 3 (mit OID 02) soll ersetzt werden, weil die Anführungszeichen falsch sind, weil diese den zweiten Feldtrenner "verdecken" und das csv Modul in dieser Zeile nur 3 Felder liest.
Code: Alles auswählen
OID;Foo;Bar;Count
01;Suse;Miller;3
02;"Invalid;Name";1
03;Peter;Blow;9
Code: Alles auswählen
#!/usr/bin/env python3
import io
import csv
from pathlib import Path
import pandas
def get_stream_from_file(fp, replace):
stream = io.StringIO()
with fp.open('r') as handle:
for line in handle:
print(f'{line=}')
try:
line = replace[line]
except KeyError:
pass
stream.write(line)
stream.seek(0)
return stream
if __name__ == "__main__":
replace = {
'02;"Invalid;Name";1\n': '02;Invalid;Name;1\n'
}
stream = get_stream_from_file(Path.cwd() / 'data.csv', replace)
# Validate the CSV
for row in csv.reader(stream, delimiter=';'):
print(f'{row=}')
# validate row
if len(row) != 4:
raise TypeException
# Get CSV as data
stream.seek(0)
data = pandas.read_csv(stream, sep=';')
print(data.to_markdown())
Code: Alles auswählen
line='OID;Foo;Bar;Count\n'
line='01;Suse;Miller;3\n'
line='02;"Invalid;Name";1\n'
line='03;Peter;Blow;9\n'
row=['OID', 'Foo', 'Bar', 'Count']
row=['01', 'Suse', 'Miller', '3']
row=['02', 'Invalid', 'Name', '1']
row=['03', 'Peter', 'Blow', '9']
| | OID | Foo | Bar | Count |
|---:|------:|:--------|:-------|--------:|
| 0 | 1 | Suse | Miller | 3 |
| 1 | 2 | Invalid | Name | 1 |
| 2 | 3 | Peter | Blow | 9 |
Problematisch wird es nur, wenn das Programm am Ende so viel RAM benötigt, dass es anfängt zu swappen.
Ein Splitten der CSV Dateien ist natürlich eine Option. Aber diese möchte ich vermeiden, weil sie extra Code und Handling erfordert.
Eure Gedanken und Idee dazu würden mich interessieren.