xml und asc Files miteinander abgleichen

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.
Benutzeravatar
__blackjack__
User
Beiträge: 13925
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@JohannX: Die letzte Frage kannst Du ganz einfach selbst beantworten in dem Du es ausprobierst. Ich vermute da ist ein Fehler drin, aber mir ist das zu lang und verworren um das jetzt wirklich durch anschauen nachprüfen zu wollen. Das sollte man vielleicht nicht als *einen* Ausdruck schreiben, denn Du hast da auch nicht wirklich einen Schritt draus gemacht, sondern nur zwei Schritte in eine zu lange Zeile gequetscht.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
JohannX
User
Beiträge: 110
Registriert: Mittwoch 27. März 2019, 17:07

Ich hab´s dann hinbekommen :)

Code: Alles auswählen

            df_Error1 = self.df_all[self.df_all["ID"] == self.ui.error_Base_1.text()]
            df_Error1_1 = df_Error1[df_Error1["DATA H"] == self.ui.error_flt_1.text()]
            time_Error1 = df_Error1_1["Offset[s]"]
            values_Error1 = df_Error1_1["DATA L"]
            name_Error1 = self.ui.error_Name_1.text() + " - " + self.ui.error_Base_1.text() + ":" + self.ui.error_flt_1.text()
            self.fig.add_trace(go.Scatter(x = time_Error1, y = values_Error1, mode = "markers", name = name_Error1), secondary_y = True)
Sirius3
User
Beiträge: 18217
Registriert: Sonntag 21. Oktober 2012, 17:20

Jetzt noch die nichtssagenden Einsen an der Variablennamen durch was sinnstiftendes ersetzen und statt +-Gestückel Stringformatierung benutzen.
JohannX
User
Beiträge: 110
Registriert: Mittwoch 27. März 2019, 17:07

Sirius3 hat geschrieben: Dienstag 20. August 2019, 14:15 Jetzt noch die nichtssagenden Einsen an der Variablennamen durch was sinnstiftendes ersetzen und statt +-Gestückel Stringformatierung benutzen.
Das werde ich alles noch machen, auch muss ich noch Kommentare schreiben damit sich die nach mir auskennen was da gemacht wird, bin nur mehr diese Woche hier als Praktikant.

2 Wünsche hat der Kollege noch geäußert, er möchte die Error´s als hex Wert haben.
Laut Internet Recherche geht das mit hex()

Code: Alles auswählen

values_Error1 = hex(df_Error1_1["DATA L"])

Aber hier kommt die Fehlermeldung

Code: Alles auswählen

Traceback (most recent call last):
  File "ascFileReader.py", line 268, in export
    values_Error1 = hex(df_Error1_1["DATA L"])
TypeError: 'Series' object cannot be interpreted as an integer
Alternativ könnte man auch vorher eine extra Variable erstellen wo der hex Wert nicht in dec umgewandelt wird

Code: Alles auswählen

         with open(self.file_asc) as file: # Filtert alle ErrorFrames heraus, welche in der asc File befinden
            buffer = StringIO('\n'.join(line.rstrip(';\n') for line in file if not line.startswith('ErrorFrames')))

         self.df_all = pd.read_csv(buffer, sep = ";", skiprows = 5, skipinitialspace = True, converters = {'DATA L': partial(int, base = 16)})
         self.df_all_hex = pd.read_csv(buffer, sep = ";", skiprows = 5, skipinitialspace = True)
         
                     df_Error1 = self.df_all_hex[self.df_all_hex["ID"] == self.ui.error_Base_1.text()]
            df_Error1_1 = df_Error1[df_Error1["DATA H"] == self.ui.error_flt_1.text()]
            time_Error1 = df_Error1_1["Offset[s]"]
            values_Error1 = df_Error1_1["DATA L"]
            name_Error1 = self.ui.error_Name_1.text() + " - " + self.ui.error_Base_1.text() + ":" + self.ui.error_flt_1.text()
            self.fig.add_trace(go.Scatter(x = time_Error1, y = values_Error1, mode = "markers", name = name_Error1), secondary_y = True)
Jedoch mag das auch nicht so recht

Code: Alles auswählen

Traceback (most recent call last):
  File "ascFileReader.py", line 122, in export
    self.df_all_hex = pd.read_csv(buffer, sep = ";", skiprows = 5, skipinitialspace = True)
  File "C:\Python3\lib\site-packages\pandas\io\parsers.py", line 685, in parser_f
    return _read(filepath_or_buffer, kwds)
  File "C:\Python3\lib\site-packages\pandas\io\parsers.py", line 457, in _read
    parser = TextFileReader(fp_or_buf, **kwds)
  File "C:\Python3\lib\site-packages\pandas\io\parsers.py", line 895, in __init__
    self._make_engine(self.engine)
  File "C:\Python3\lib\site-packages\pandas\io\parsers.py", line 1135, in _make_engine
    self._engine = CParserWrapper(self.f, **self.options)
  File "C:\Python3\lib\site-packages\pandas\io\parsers.py", line 1906, in __init__
    self._reader = parsers.TextReader(src, **kwds)
  File "pandas\_libs\parsers.pyx", line 543, in pandas._libs.parsers.TextReader.__cinit__
pandas.errors.EmptyDataError: No columns to parse from file
Benutzeravatar
__blackjack__
User
Beiträge: 13925
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Man könnte die auch gar nicht erst in Zahlen umwandeln dann braucht man sie später nicht zurückwandeln.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
JohannX
User
Beiträge: 110
Registriert: Mittwoch 27. März 2019, 17:07

Anscheinend funktioniert das so nicht ganz mit plotly, auch wenn ich einen hex wert erhalte, zeigt mir Plotly dies immer als dec an
Aber dies ist eher ein nice-to-have
JohannX
User
Beiträge: 110
Registriert: Mittwoch 27. März 2019, 17:07

Eines habe ich noch und dann wars das.
Es werden die ErrorFrames herausgefiltert, jetzt ist es noch erwünscht, diese seperat mit plotly auszugeben.

Code: Alles auswählen

         with open(self.file_asc) as file: # Filtert alle ErrorFrames heraus, welche in der asc File befinden
            buffer = StringIO('\n'.join(line.rstrip(';\n') for line in file if not line.startswith('ErrorFrames')))
Das problem ist nur die Zeit

Code: Alles auswählen

27.03.2019;17:18:26;000000470.243600;1100001x;800A6AD0;00000010;
ErrorFrames: 0 4702439 1 0 0 1
27.03.2019;17:18:26;000000470.243900;10008x;00000000;00000000;
27.03.2019;17:18:26;000000470.246200;DD00011x;8002019E;00000088;
ErrorFrames: 0 4702644 1 0 0 2
27.03.2019;17:18:26;000000470.264400;20008x;00000000;00000000;
Bei den Errorframes ist die Zeit quasi nach dem nuller, "4702439" dies sind jedoch ms und keine sekunden.
JohannX
User
Beiträge: 110
Registriert: Mittwoch 27. März 2019, 17:07

Hab´s soweit getestet

Code: Alles auswählen

            with open(self.file_asc) as file_errorframes:
               buffer_errorframes = StringIO('\n'.join(line.rstrip(';\n') for line in file_errorframes if line.startswith('ErrorFrames')))
               df_all_errorframes = pd.read_csv(buffer_errorframes)
               print(df_all_errorframes.head())
Was hierbei rauskommt ist

Code: Alles auswählen

   ErrorFrames: 0 4702439 1 0 0 1
0  ErrorFrames: 0 4702644 1 0 0 2
1  ErrorFrames: 0 4733128 1 0 0 3
2  ErrorFrames: 0 4749315 1 0 0 4
3  ErrorFrames: 0 4803094 1 0 0 5
4  ErrorFrames: 0 4831065 1 0 0 6
Wobei anscheinend die erste Zeile als Überschrift dient, jedoch benötige ich auch diese Zeile.
Hat jemand eine Idee?
Sirius3
User
Beiträge: 18217
Registriert: Sonntag 21. Oktober 2012, 17:20

@JohannX: hast Du schon die Dokumentation zu pd.read_csv gelesen?
Benutzeravatar
snafu
User
Beiträge: 6831
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Eigentlich braucht man die ganze Vorarbeit nicht, wenn man pandas richtig benutzt:

Code: Alles auswählen

from io import StringIO
import pandas as pd

TEST_STREAM = StringIO("""\
27.03.2019;17:18:26;000000470.243600;1100001x;800A6AD0;00000010;
ErrorFrames: 0 4702439 1 0 0 1
27.03.2019;17:18:26;000000470.243900;10008x;00000000;00000000;
27.03.2019;17:18:26;000000470.246200;DD00011x;8002019E;00000088;
ErrorFrames: 0 4702644 1 0 0 2
27.03.2019;17:18:26;000000470.264400;20008x;00000000;00000000;""")

def parse_data(stream):
    df = pd.read_csv(stream, sep=';', usecols=range(6), header=None)
    errors = df[0].str.startswith('ErrorFrames')
    return (df[~errors], df[errors])

def main():
    ok, errors = parse_data(TEST_STREAM)
    print(ok)
    print(errors)

if __name__ == '__main__':
    main()
Benutzeravatar
snafu
User
Beiträge: 6831
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Und hier werden die Fehler als eigener DataFrame geliefert:

Code: Alles auswählen

from io import StringIO
import pandas as pd

TEST_STREAM = StringIO("""\
27.03.2019;17:18:26;000000470.243600;1100001x;800A6AD0;00000010;
ErrorFrames: 0 4702439 1 0 0 1
27.03.2019;17:18:26;000000470.243900;10008x;00000000;00000000;
27.03.2019;17:18:26;000000470.246200;DD00011x;8002019E;00000088;
ErrorFrames: 0 4702644 1 0 0 2
27.03.2019;17:18:26;000000470.264400;20008x;00000000;00000000;""")

def parse_data(stream):
    df = pd.read_csv(stream, sep=';', usecols=range(6), header=None)
    is_error = df[0].str.startswith('ErrorFrames')
    errors = df[0][is_error].str.split()
    return df[~is_error], pd.DataFrame(list(errors))

def main():
    df, errors = parse_data(TEST_STREAM)
    print(df, errors, sep='\n')

if __name__ == '__main__':
    main()
Unschön daran ist, dass man den DataFrame für die Fehler neu bauen muss und dass dabei die Original-Indexwerte futsch sind. Das geht bestimmt noch besser...
Benutzeravatar
snafu
User
Beiträge: 6831
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Nochmal überarbeitet mit Spaltennamen (soweit ich diese herleiten konnte) und ein paar Verbesserungen für die Fehler-Frames. Sie haben jetzt den Original-Index. Zu beachten ist allerdings, dass sich die Spalten unterschieden.

Code: Alles auswählen

from io import StringIO
import pandas as pd

HEADINGS = ['Datum', 'Zeit', 'Dauer', 'A', 'B', 'C', 'D']

TEST_STREAM = StringIO("""\
27.03.2019;17:18:26;000000470.243600;1100001x;800A6AD0;00000010;
ErrorFrames: 0 4702439 1 0 0 1
27.03.2019;17:18:26;000000470.243900;10008x;00000000;00000000;
27.03.2019;17:18:26;000000470.246200;DD00011x;8002019E;00000088;
ErrorFrames: 0 4702644 1 0 0 2
27.03.2019;17:18:26;000000470.264400;20008x;00000000;00000000;""")

def parse_data(stream):
    df = pd.read_csv(stream, sep=';', usecols=range(6), names=HEADINGS[:-1])
    is_error = df.Datum.str.startswith('Error')
    errors = df.Datum[is_error].str.split(expand=True)
    errors.columns = HEADINGS
    errors = errors.drop(columns=['Datum']).astype(int)
    errors.Dauer = errors.Dauer.astype(float) / 1000
    return (df[~is_error], errors)

def main():
    df, errors = parse_data(TEST_STREAM)
    print(df, errors, sep='\n')

if __name__ == '__main__':
    main()
JohannX
User
Beiträge: 110
Registriert: Mittwoch 27. März 2019, 17:07

Super Danke dir snafu!
Habs gestern eh auch selber hinbekommen, aber mit deinem Code sieht es besser aus :)

Das Projekt funktioniert jetzt soweit, Variablennamen wurden noch korrigiert usw...
Wurde als .exe via pyinstaller exportiert und läuft Fehlerfrei.

Ich danke für die Großartige Unterstützung hier :)

Mache mich nun auf das letzte Projekt, ob ich Fertig werde oder nicht ist egal. Was ich alles schaffen konnte werde ich morgen weitergeben
Antworten