Kann mir jemand dabei helfen?
Das Programm sollte alle TXT Datei in ein CSV Dateiformat umwandeln
aber es wird einen Fehler entstehen .... ich weiß leider nicht, wo es ran liegt .
# coding: utf-8
import pandas as pd
import os
#dirPath = "C:\\Users\\Kevin\\Documents\\SharePoint\\Privat - Workspace\\1 IP1\\Daten aus Versuchen etc\\Maische_Schichtdicke-5mm_S-var_L-var\\"
#additionalLabels = ['Saccharose(g)', 'Lactose(g)']
#_countBeforeValues = [4, 5]
def readSpectrometerFiles(dirPath, additionalLabels=[], _countBeforeValues=[], fileNameOutput=False):
fileNames = os.listdir(dirPath)
csvFileName = 'LindaManuTest' + '_'.join(additionalLabels) + '_' + '_'.join((str(x) for x in _countBeforeValues)) + '.csv' #Namen eingeben
if csvFileName not in fileNames:
df = pd.DataFrame()
for fileName in fileNames:
if fileNameOutput:
print(fileName)
if fileName[-4:].lower() != '.txt':
continue
values = dict()
gotWavelengths = False
for line in open(dirPath + fileName):
line = line[:-1]
if line.find(': ') != -1:
arguments = line.split('\t')
i = 1
while i < len(arguments):
if arguments.find(': ') == -1:
arguments[i-1] += ' ' + arguments.pop(i)
else:
i += 1
for argument in arguments:
parts = argument.split(': ')
values[parts[0]] = parts[1]
else:
if gotWavelengths:
intensities = line.split('\t')
for i, intensity in enumerate(intensities):
values['wavelength_' + wavelengths] = intensity
else:
wavelengths = line.split('\t')
gotWavelengths = True
fileNameParts = fileName[:-4].split('_')
for i, pos in enumerate(_countBeforeValues):
values[additionalLabels] = ''.join(filter(lambda x: not x.isalpha(), fileNameParts[pos])).replace(',', '.').strip()
dataPoint = pd.Series(values)
df = df.append(dataPoint, ignore_index=True)
df.to_csv(dirPath+csvFileName, index=False)
return pd.read_csv(dirPath+csvFileName)
if __name__ == "__main__":
readSpectrometerFiles(dirPath = "C:\\Users\\ramad\\Desktop\\Messungen\\No\\",
additionalLabels = ["Yeast","Beer","Plato"],
_countBeforeValues = [2,4,6],
fileNameOutput = True)
Vielen Dank
Fehler /Hilfe
Dein Code gehört zwischen Code-tags, damit die Einrückung bestehen bleibt. Die Tags werden automatisch eingefügt, wenn du den </>-Button im vollständigen Editor drückst.
Bitte poste auch die vollständige Fehlermeldung, die du bekommst.
Bitte poste auch die vollständige Fehlermeldung, die du bekommst.
Hallo Ramo.2022,
ich probiere gerade deine Vorgehensweise zu verstehen.
Als Hinweis:
Pfaderstellung: Bitte mit pathlib und nicht mit strings zusammenstückeln, hier kann man auch sehr komfortabel mit rglob die passenden Dateien durchsuchen
Wieso nimmst du nicht von Anfang an read_csv? Das geht auch mit txt-Dateien.
Du gibt als return Wert der Funktion ein df.read_csv() zurück? Benutzt es aber nicht? Wofür dann überhaupt die Rückgabe?
Mir kommt vor als würdest du für diesen Fall einen eigenen read_csv bauen? Warum eigentlich? Lt. den Pfadbezeichnungen würde ich darauf tippen, dass die Dateien durch ein Programm erstellt werden und daher wohl immer gleich weggespeichert sind?
ich probiere gerade deine Vorgehensweise zu verstehen.
Als Hinweis:
Pfaderstellung: Bitte mit pathlib und nicht mit strings zusammenstückeln, hier kann man auch sehr komfortabel mit rglob die passenden Dateien durchsuchen
Wieso nimmst du nicht von Anfang an read_csv? Das geht auch mit txt-Dateien.
Du gibt als return Wert der Funktion ein df.read_csv() zurück? Benutzt es aber nicht? Wofür dann überhaupt die Rückgabe?
Mir kommt vor als würdest du für diesen Fall einen eigenen read_csv bauen? Warum eigentlich? Lt. den Pfadbezeichnungen würde ich darauf tippen, dass die Dateien durch ein Programm erstellt werden und daher wohl immer gleich weggespeichert sind?
sparrow hat geschrieben: Montag 30. Mai 2022, 10:33 Dein Code gehört zwischen Code-tags, damit die Einrückung bestehen bleibt. Die Tags werden automatisch eingefügt, wenn du den </>-Button im vollständigen Editor drückst.
Bitte poste auch die vollständige Fehlermeldung, die du bekommst.
Vielen Dank für deine Antwort
das was ich bekommen hab :
runfile('C:/Users/ramad/Downloads/Parser_pw/Parser_pw.py', wdir='C:/Users/ramad/Downloads/Parser_pw')
G023_SSS_L_B_R_000172.TXT
Traceback (most recent call last):
File "C:\Users\ramad\Downloads\Parser_pw\Parser_pw.py", line 52, in <module>
readSpectrometerFiles(dirPath = "C:\\Users\\ramad\\Desktop\\Messungen\\Test\\",
File "C:\Users\ramad\Downloads\Parser_pw\Parser_pw.py", line 45, in readSpectrometerFiles
values[additionalLabels] = ''.join(filter(lambda x: not x.isalpha(), fileNameParts[pos])).replace(',', '.').strip()
IndexError: list index out of range
runfile('C:/Users/ramad/Downloads/Parser_pw/Parser_pw.py', wdir='C:/Users/ramad/Downloads/Parser_pw')
G023_SSS_L_B_R_000172.TXT
Traceback (most recent call last):
File "C:\Users\ramad\Downloads\Parser_pw\Parser_pw.py", line 52, in <module>
readSpectrometerFiles(dirPath = "C:\\Users\\ramad\\Desktop\\Messungen\\Test\\",
File "C:\Users\ramad\Downloads\Parser_pw\Parser_pw.py", line 45, in readSpectrometerFiles
values[additionalLabels] = ''.join(filter(lambda x: not x.isalpha(), fileNameParts[pos])).replace(',', '.').strip()
IndexError: list index out of range
G023_SSS_L_B_R_000172.TXT
Traceback (most recent call last):
File "C:\Users\ramad\Downloads\Parser_pw\Parser_pw.py", line 52, in <module>
readSpectrometerFiles(dirPath = "C:\\Users\\ramad\\Desktop\\Messungen\\Test\\",
File "C:\Users\ramad\Downloads\Parser_pw\Parser_pw.py", line 45, in readSpectrometerFiles
values[additionalLabels] = ''.join(filter(lambda x: not x.isalpha(), fileNameParts[pos])).replace(',', '.').strip()
IndexError: list index out of range
derElch hat geschrieben: Montag 30. Mai 2022, 12:31 Hallo Ramo.2022,
ich probiere gerade deine Vorgehensweise zu verstehen.
Als Hinweis:
Pfaderstellung: Bitte mit pathlib und nicht mit strings zusammenstückeln, hier kann man auch sehr komfortabel mit rglob die passenden Dateien durchsuchen
Wieso nimmst du nicht von Anfang an read_csv? Das geht auch mit txt-Dateien.
Du gibt als return Wert der Funktion ein df.read_csv() zurück? Benutzt es aber nicht? Wofür dann überhaupt die Rückgabe?
Mir kommt vor als würdest du für diesen Fall einen eigenen read_csv bauen? Warum eigentlich? Lt. den Pfadbezeichnungen würde ich darauf tippen, dass die Dateien durch ein Programm erstellt werden und daher wohl immer gleich weggespeichert sind?
Vielen Dank füe deine Antwort
wie kann ich das machen ?
- __blackjack__
- User
- Beiträge: 13999
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Ramo.2022: Was verstehst Du denn an der Ausnahme nicht? `fileNameParts` ist sehr wahrscheinlich nicht das was Du denkst was es ist. Es wird auch an der falschen Stelle berechnet, denn in jedem Schleifendurchlauf in dem das definiert wird, hat das das gleiche Ergebnis, weil die Schleife da überhaupt gar keinen Einfluss drauf hat. Zudem wird dieses immer gleiche Ergebnis ja auch erst *nach* der Schleife verwendet. Falls die Datei leer ist, wäre der Name im Moment dann auch gar nicht definiert, und es wird beim Zugriff auf den nicht-definierten Namen zu einer Ausnahme führen.
Ich würde auch noch mal ganz dringend `pathlib.Path` ans Herz legen. Und da dann sowieso einiges umgeschrieben werden muss, kannst Du auch gleich die Namensschreibweisen anpassen: Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase). Ein einzelner führender Unterstrich wird von vielen benutzt um Namen zu kennzeichnen die nicht verwendet werden, damit der Leser und statische Prüfwerkzeuge wissen, dass das Absicht ist, und kein Fehler oder noch unvollständiger Code. `_countBeforeValues` wird aber verwendet.
`str.find()` verwendet man nicht dafür um zu prüfen ob eine Teilzeichenkette in einer anderen enthalten ist oder nicht. Dafür gibt es die Operatoren ``in`` und ``not in``, je nach dem welchen der beiden Fälle man prüfen möchte.
``line[:-1]`` ist kein robuster Weg um Zeilenendezeichen zu entfernen. Es kann passieren, dass mehr als ein Zeichen vorhanden ist, aber auch bei der letzten Zeile in Dateien, gar kein Zeilenendekennzeichen vorhanden ist, und man ein Zeichen das zu einem Wert gehört, weg wirft. Wenn man generell „whitespace“ am Zeilenende entfernen will/darf, dann ``line.rstrip()`` — wenn man es auf die üblichen Zeichen für Wagenrücklauf und Zeilenvorschub beschränken will/muss, dann ``line.rstrip("\r\n")``.
Wenn ich das richtig sehe sind beide Fälle von `enumerate()` eigentlich ein Fall für `zip()` weil der mit `enumerate()` erzeugte Laufindex als Indexzugriff in eine ”parallele” Datenstruktur verwendet wird.
Was da mit `arguments` gemacht wird ist recht kryptisch ohne das wissen wie die Daten aufgebaut sind und was daraus werden soll. Ich vermute auch stark, dass man das einfacher und lesbarer hinbekommen kann, beispielsweise mit `itertools.groupby()` oder etwas aus dem `more_itertools`-Modul.
Das ganze ist vielleicht auch etwas viel für *eine* Funktion. Der Schleifeninhalt, also das verarbeiten/lesen *einer* Datei könnte sicher in eine eigene Funktion herausgezogen werden.
Ich würde auch noch mal ganz dringend `pathlib.Path` ans Herz legen. Und da dann sowieso einiges umgeschrieben werden muss, kannst Du auch gleich die Namensschreibweisen anpassen: Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase). Ein einzelner führender Unterstrich wird von vielen benutzt um Namen zu kennzeichnen die nicht verwendet werden, damit der Leser und statische Prüfwerkzeuge wissen, dass das Absicht ist, und kein Fehler oder noch unvollständiger Code. `_countBeforeValues` wird aber verwendet.
`str.find()` verwendet man nicht dafür um zu prüfen ob eine Teilzeichenkette in einer anderen enthalten ist oder nicht. Dafür gibt es die Operatoren ``in`` und ``not in``, je nach dem welchen der beiden Fälle man prüfen möchte.
``line[:-1]`` ist kein robuster Weg um Zeilenendezeichen zu entfernen. Es kann passieren, dass mehr als ein Zeichen vorhanden ist, aber auch bei der letzten Zeile in Dateien, gar kein Zeilenendekennzeichen vorhanden ist, und man ein Zeichen das zu einem Wert gehört, weg wirft. Wenn man generell „whitespace“ am Zeilenende entfernen will/darf, dann ``line.rstrip()`` — wenn man es auf die üblichen Zeichen für Wagenrücklauf und Zeilenvorschub beschränken will/muss, dann ``line.rstrip("\r\n")``.
Wenn ich das richtig sehe sind beide Fälle von `enumerate()` eigentlich ein Fall für `zip()` weil der mit `enumerate()` erzeugte Laufindex als Indexzugriff in eine ”parallele” Datenstruktur verwendet wird.
Was da mit `arguments` gemacht wird ist recht kryptisch ohne das wissen wie die Daten aufgebaut sind und was daraus werden soll. Ich vermute auch stark, dass man das einfacher und lesbarer hinbekommen kann, beispielsweise mit `itertools.groupby()` oder etwas aus dem `more_itertools`-Modul.
Das ganze ist vielleicht auch etwas viel für *eine* Funktion. Der Schleifeninhalt, also das verarbeiten/lesen *einer* Datei könnte sicher in eine eigene Funktion herausgezogen werden.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
Hallo Ramo.2022,Ramo.2022 hat geschrieben: Montag 30. Mai 2022, 14:36derElch hat geschrieben: Montag 30. Mai 2022, 12:31 Hallo Ramo.2022,
ich probiere gerade deine Vorgehensweise zu verstehen.
Als Hinweis:
Pfaderstellung: Bitte mit pathlib und nicht mit strings zusammenstückeln, hier kann man auch sehr komfortabel mit rglob die passenden Dateien durchsuchen
Wieso nimmst du nicht von Anfang an read_csv? Das geht auch mit txt-Dateien.
Du gibt als return Wert der Funktion ein df.read_csv() zurück? Benutzt es aber nicht? Wofür dann überhaupt die Rückgabe?
Mir kommt vor als würdest du für diesen Fall einen eigenen read_csv bauen? Warum eigentlich? Lt. den Pfadbezeichnungen würde ich darauf tippen, dass die Dateien durch ein Programm erstellt werden und daher wohl immer gleich weggespeichert sind?
Vielen Dank füe deine Antwort
wie kann ich das machen ?
um welche Dateigröße handelt es sich hier? Hast / Darfst du einen Teil (Anfang, Mitte, Ende) der *.txt hier öffentlich posten?
Wenn ja, dann bitte mit Code Tags. Da wir ansonsten nur raten können wie die passende csv aussieht.
Ich würde die Funktionen ebenfalls trennen, wie schon von __blackjack__ geschrieben.
Als Beispiel:
- finden_der_passenden_Dateien
- verarbeiten_der_zusatzinformationen
- konvertierung_der_daten
- rausspielen_der_datei
- __blackjack__
- User
- Beiträge: 13999
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Ramo.2022: Statt den CSV-Dateinamen linear in den Dateinamen des Verzeichnis zu suchen, könnte man auch einfach testen ob die Datei existiert. Dann muss man im Vorfeld nicht zwingend eine Liste mit dem gesamten Verzeichnisinhalt erstellen.
Das `outputFilename`-Flag sieht so ein bisschen nach Debugging-Hilfe aus. So etwas sollte nicht in der API auftauchen und ist eher ein Fall für Logging. Entweder mit dem `logging`-Modul aus der Standardbibliothek oder einem externen Paket wie `loguru`. Alternativ könnte man auch eine Rückruffunktion als Argument verwenden.
Das `gotWavelengths`-Flag kann man sich sparen wenn man `wavelength` selbst dafür benutzt und das mit `None` initialisiert und darauf testet.
Dateien die man öffnet sollte man auch explizit wieder schliessen. Dazu bietet sich die ``with``-Anweisung an um das sicherzustellen.
Beim öffnen von Textdateien sollte man immer explizit die Kodierung angeben, sonst ist das vom System abhängig auf dem das am Ende läuft.
Ungetestet:
Das `outputFilename`-Flag sieht so ein bisschen nach Debugging-Hilfe aus. So etwas sollte nicht in der API auftauchen und ist eher ein Fall für Logging. Entweder mit dem `logging`-Modul aus der Standardbibliothek oder einem externen Paket wie `loguru`. Alternativ könnte man auch eine Rückruffunktion als Argument verwenden.
Das `gotWavelengths`-Flag kann man sich sparen wenn man `wavelength` selbst dafür benutzt und das mit `None` initialisiert und darauf testet.
Dateien die man öffnet sollte man auch explizit wieder schliessen. Dazu bietet sich die ``with``-Anweisung an um das sicherzustellen.
Beim öffnen von Textdateien sollte man immer explizit die Kodierung angeben, sonst ist das vom System abhängig auf dem das am Ende läuft.
Ungetestet:
Code: Alles auswählen
#!/usr/bin/env python3
from pathlib import Path
import pandas as pd
from more_itertools import split_before
# directory_path = Path(R"C:\Users\Kevin\Documents\SharePoint\Privat - Workspace\1 IP1\Daten aus Versuchen etc\Maische_Schichtdicke-5mm_S-var_L-var")
# additional_labels = ["Saccharose(g)", "Lactose(g)"]
# count_before_values = [4, 5]
def read_spectrometer_file(file_path):
values = {}
with file_path.open(encoding="ascii") as lines:
wavelengths = None
for line in lines:
parts = line.rstrip("\r\n").split("\t")
if ": " in line:
groups = split_before(parts, lambda part: ": " in part)
values.update(
argument.split(": ") for argument in map(" ".join, groups)
)
else:
if wavelengths is None:
wavelengths = parts
else:
values.update(
(f"wavelength_{wavelength}", intensity)
for wavelength, intensity in zip(wavelengths, parts)
)
return values
def read_spectrometer_files(
directory_path,
additional_labels=(),
count_before_values=(),
filename_callback=lambda filename: None,
):
labels_text = "_".join(additional_labels)
counts_text = "_".join(map(str, count_before_values))
csv_file_path = (
directory_path / f"LindaManuTest{labels_text}_{counts_text}.csv"
)
if csv_file_path.exists():
data = pd.read_csv(csv_file_path)
else:
data_parts = []
for path in directory_path.glob("*.txt"):
filename_callback(path.name)
if path.is_file():
values = read_spectrometer_file(path)
filename_parts = path.stem.split("_")
for label, pos in zip(additional_labels, count_before_values):
values[label] = (
"".join(
filter(
lambda x: not x.isalpha(),
filename_parts[pos],
)
)
.replace(",", ".")
.strip()
)
data_parts.append(pd.Series(values))
data = pd.concat(data_parts, ignore_index=True)
data.to_csv(csv_file_path, index=False)
return data
if __name__ == "__main__":
read_spectrometer_files(
Path(R"C:\Users\ramad\Desktop\Messungen\No"),
["Yeast", "Beer", "Plato"],
[2, 4, 6],
print,
)
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
- __blackjack__
- User
- Beiträge: 13999
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Ramo.2022: Noch eine Überarbeitung: `additional_labels` und `count_before_values` sind ja ”parallele Listen”. Das ist unübersichtlich und fehleranfällig. Man sollte zusammengehörende Informationen nicht so auf mehrere Listen verteilen, sondern in eine Liste zum Beispiel als Tupel stecken. Also das was im Code letztlich ja mit `zip()` gemacht wird.
Das entfernen von unerwünschten Zeichen aus den Daten die aus den Dateinamen geholt werden, lässt sich mit dem `re`-Modul etwas weniger kompliziert ausdrücken.
Ungetestet:
Das entfernen von unerwünschten Zeichen aus den Daten die aus den Dateinamen geholt werden, lässt sich mit dem `re`-Modul etwas weniger kompliziert ausdrücken.
Ungetestet:
Code: Alles auswählen
#!/usr/bin/env python3
import re
from pathlib import Path
import pandas as pd
from more_itertools import split_before
# directory_path = Path(R"C:\Users\Kevin\Documents\SharePoint\Privat - Workspace\1 IP1\Daten aus Versuchen etc\Maische_Schichtdicke-5mm_S-var_L-var")
# filename_label_infos = [("Saccharose(g)", 4), ("Lactose(g)", 5)]
def read_spectrometer_file(file_path):
values = {}
with file_path.open(encoding="ascii") as lines:
wavelengths = None
for line in lines:
parts = line.rstrip("\r\n").split("\t")
if ": " in line:
groups = split_before(parts, lambda part: ": " in part)
values.update(
argument.split(": ") for argument in map(" ".join, groups)
)
else:
if wavelengths is None:
wavelengths = parts
else:
values.update(
(f"wavelength_{wavelength}", intensity)
for wavelength, intensity in zip(wavelengths, parts)
)
return values
def clean_filename_part(text):
return re.sub(r"\w+", "", text).replace(",", ".").strip()
def extract_labels_from_filename(filename_label_infos, path):
filename_parts = path.stem.split("_")
return {
label: clean_filename_part(filename_parts[index])
for label, index in filename_label_infos
}
def read_spectrometer_files(
directory_path,
filename_label_infos=(),
filename_callback=lambda filename: None,
):
labels_text = "_".join(label for label, _ in filename_label_infos)
counts_text = "_".join(str(index) for _, index in filename_label_infos)
csv_file_path = (
directory_path / f"LindaManuTest{labels_text}_{counts_text}.csv"
)
try:
data = pd.read_csv(csv_file_path)
except FileNotFoundError:
data_parts = []
for path in directory_path.glob("*.txt"):
filename_callback(path.name)
if path.is_file():
values = read_spectrometer_file(path)
values.update(
extract_labels_from_filename(filename_label_infos, path)
)
data_parts.append(pd.Series(values))
data = pd.concat(data_parts, ignore_index=True)
data.to_csv(csv_file_path, index=False)
return data
if __name__ == "__main__":
read_spectrometer_files(
Path(R"C:\Users\ramad\Desktop\Messungen\No"),
[("Yeast", 2), ("Beer", 4), ("Plato", 6)],
print,
)
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis