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
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Man darf übrigens bei Fragen zu einem komplett neuen Thema gern einen neuen Thread aufmachen. Mit XML hat das hier ja schon lange nichts mehr zu tun...

EDIT: Achso, das steht nun mit der vorliegenden ASC-Datei in Zusammenhang. Es ist trotzdem unschön für spätere Leser, wenn man einen Sammelthread für all seine Fragen bezüglich eines Projektes aufmacht. Denn dann muss auch viel uninteressanter Kram durchforstet werden. Daher bei der Nutzung des Forums vielleicht nicht nur sich selbst sehen, sondern auch die Nutzergemeinschaft im Blick haben. Das wäre sehr nett. :)
JohannX
User
Beiträge: 110
Registriert: Mittwoch 27. März 2019, 17:07

kbr hat geschrieben: Donnerstag 1. August 2019, 17:18 @JohannX: was passiert Deine Meinung nach eigentlich hier:

Code: Alles auswählen

values_Name_1 = df_Name_1["DATA L"].apply(lambda v: self.liste[0][1])
Also meines Wissens nach wird hier self.liste[0][1] diese Formel eingesetzt v*(5/1024)*9.980487805
Das .apply Berechnet den Wert zu welcher sich in df_Name_1["DATA L"] befindet
Das ganze wird dann in eine neue Variable gespeichert
Denke dass das so Richtig ist.
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Das schöne an Python ist, dass man gar nicht 'denken' (im Sinne von vermuten) muss, man kann das einfach ausprobieren.
Befinden sich denn hinterher die korrekten Daten in values_Name_1? So wie du sie erwartest?
Ich sehe zumindest nicht, warum die von dir genannte Formel dort eingesetzt werden sollte. Was ist denn der Wert von self.liste[0][1] (der Name ist noch immer schlecht, das mit den Indexzugriffen auch. Wäre das gut gelöst, müsste man das nicht zum 18 Mal fragen).
JohannX
User
Beiträge: 110
Registriert: Mittwoch 27. März 2019, 17:07

Aber ich habe jetzt in de asc File herausgefunden warum das so nicht hinhaut:
Es ist ein Error enthalten
ErrorFrames: 0 6611826 1 0 0 12
Das dürfte mir den Fehler verursachen...

Also muss ich vorher die asc File nach solchen leeren Zeilen durchsuchen und entfernen.
Dieser Vorgang sollte korrekt sein
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Es wird spätestens an der von snafu angesprochenen Stelle nicht mehr korrekt sein.
JohannX
User
Beiträge: 110
Registriert: Mittwoch 27. März 2019, 17:07

Das Programm funktioniert soweit wie es soll.
Zwei Sachen müssen noch etwas angepasst werden, wobei ich das erste schon geschafft habe.

Das zweite und etwas aufwendigere Problem ist folgendes:
Im asc File sind noch weitere Daten vorhanden als die von dem xml File, diese sind Fehlerdaten welche so aussehen könnten: 1100001x
Sie haben immer einen 1 und ein x am Ende, davor kann es Variieren.

ABER:
Es darf nicht die Daten vom xml File miteinbeziehen, da diese so aussehen,

Code: Alles auswählen

DD00011x
1100013
1100015
könnte man meinen dass DD00011x auch ein Fehler wäre, ist er aber nicht.

Wie kann ich dieses Vorhaben umsetzen?
Wenn am Ende 1x steht und nicht im xml steht, dann in eine neue Variable speichern und plotten via plotly
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Du schaust einfach, ob die ID mit 1x endet und nicht im XML-File steht.
Niemand hier weiß, was Du für Datenstrukturen hast und was speichern und plotten genau bedeutet.
JohannX
User
Beiträge: 110
Registriert: Mittwoch 27. März 2019, 17:07

Ich habe nach Wunsch den Kollegen nun 2 Input Felder zu der GUI hinzugefügt, so können 2 ID´s welche irgendwelche Meldungen sein können.
Soweit funktioniert das auch und kann als Diagramm via Plotly ausgegeben werden.

Eine Frage habe ich hier allerdings, bei einer ID z.B. 1100001x sind mehrere unterschiedliche Daten vorhanden

Code: Alles auswählen

1100001x;800A5F20
1100001x;800A5F6D
1100001x;800A5FE1
1100001x;800A5FEF
1100001x;800A6024
1100001x;800A6039
1100001x;800A6071
1100001x;800A6A7D
1100001x;800A6B29
1100001x;800A6B60
1100001x;800A6B6E
1100001x;800A6B8D
1100001x;800A7229
1100001x;800A7279
1100001x;800A7319
1100001x;800A73B9
1100001x;800A5F6D
Das ist nur ein kleiner Auszug von der csv Datei.

Da dieses Unterfangen mein "können" überfordern, muss ich hier nochmals nachfragen.
Wie stelle ich es am besten an, damit alle gleichen Daten von der ID 1100001x seperat abgespeichert werden und diese mit hilfe von plotly in das Diagramm angezeigt werden kann?

Derzeit sieht mein Code so aus:

Code: Alles auswählen

            df_Error1 = self.df_all[self.df_all["ID"] == self.ui.line_BaseID_11.text()]
            time_Error1 = df_Error1["Offset[s]"] # Holt sich die Zeit
            values_Error1 = df_Error1["DATA L"]
            name_Error1 = self.ui.line_Name_11.text() # Name für Layout
            self.fig.add_trace(go.Scatter(x = time_Error1, y = values_Error1, mode = "markers", name = name_Error1))
Hier werden jedoch alle 1100001x zusammengefasst ausgegeben
JohannX
User
Beiträge: 110
Registriert: Mittwoch 27. März 2019, 17:07

Ich wage meine Versuche mit regex und das Problem zu lösen.
Das ist der Code:

Code: Alles auswählen

import re
import sys
import os
import pandas as pd
from io import StringIO

neue = []

with open("DUT4_Slow_Decrease_Increase_10V_Messages_All_Flipx_.asc", "r") as file:
        buffer = StringIO('\n'.join(line.strip(';\n') for line in file if not line.startswith('ErrorFrames')))
        for lines in buffer:
                neue.append(lines)

regex = r'1100001x;([0-9a-fA-F]+)'
matches = re.finditer(regex, neue, re.MULTILINE)

for matchNum, match in enumerate(matches, start=1):
    
    print ("Match {matchNum} was found at {start}-{end}: {match}".format(matchNum = matchNum, start = match.start(), end = match.end(), match = match.group()))
    
    for groupNum in range(0, len(match.groups())):
        groupNum = groupNum + 1
        
        print ("Group {groupNum} found at {start}-{end}: {group}".format(groupNum = groupNum, start = match.start(groupNum), end = match.end(groupNum), group = match.group(groupNum)))
Doch leider kommt diese Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "regex.py", line 17, in <module>
    matches = re.finditer(regex, neue, re.MULTILINE)
  File "C:\Python3\lib\re.py", line 230, in finditer
    return _compile(pattern, flags).finditer(string)
TypeError: expected string or bytes-like object
__deets__
User
Beiträge: 14542
Registriert: Mittwoch 14. Oktober 2015, 14:29

Reguelaere Ausdruecke arbeiten auf Strings (oder Bytes). Nicht auf Listen.
Benutzeravatar
__blackjack__
User
Beiträge: 13112
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Ich frage mich auch was das überhaupt werden soll – das sind doch immer noch durch Semikolon getrennte CSV-Daten die danach in einen Pandas-DataFrame gefüttert werden, oder? Warum will man da jetzt *vorher* irgendwie mit regulären Ausdrücken Werte für eine Spalte suchen wenn man das viel einfacher und robuster um DataFrame machen könnte‽
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
JohannX
User
Beiträge: 110
Registriert: Mittwoch 27. März 2019, 17:07

Ich lese die csv Datei mittels Pandas ein und filtere hier ErrorFrames heraus:

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.strip(';\n') for line in file if not line.startswith('ErrorFrames')))

         # Zurechtschneiden und Filtern des asc Files
         self.df_all = pd.read_csv(buffer, sep = ";", skiprows = 5, skipinitialspace = True, converters = {'DATA L': partial(int, base = 16)})
         # Speichert den Filenamen für das Ploten
         file_title = os.path.basename(self.file_asc)
         
                  print(self.df_all.head())
Die Ausgabe davon:

Code: Alles auswählen

   Start Date      Time  Offset[s]        ID    DATA H      DATA L
0  27.03.2019  17:18:26     0.0010       AEx  00000000  1279872594
1  27.03.2019  17:18:26     0.0013  2200000x  700017E9  1279872594
2  27.03.2019  17:18:26     0.0016  DD00011x  8002019E         223
3  27.03.2019  17:18:26     0.0019  DD00011x  8002019E         210
4  27.03.2019  17:18:26     0.0045  1100001x  800A7229           2
Das ist super Einfach mit Pandas, jetzt stehe ich seit Gestern an dem Problem, dass ich gern von der Spalte "ID" alle Fehler mit 1100001x haben möchte, davon allerdings nur den Fehler z.B: 800A7229 welcher sich in der Spalte "DATA H" befindet!
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Das `line.strip(';\n')` sollte ein `line.rstrip(';\n')` sein.
Und in der ID-Spalte stehen keine Spalten-Namen drin, so dass der Aufruf nicht funktioniert. Was hast Du Dir denn bei der ersten Zeile gedacht?

Was Du brauchst sind Vektoren mit Wahrheitswerten, die Du logisch verknüpfen kannst.
Benutzeravatar
__blackjack__
User
Beiträge: 13112
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@JohannX: Naja dann mach das doch einfach. Du weisst ja wie man alle Datansätze mit der ID 1100001x selektiert. Und Du weisst wie man alle Datensätze mit "DATA H"-Wert 800A7229 selektiert. Grundsätzlich könntest Du das Problem also schon lösen. Statt zwei Schritte zu machen die Du bereits kennst, kann man das auch in einen Schritt kombinieren.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
JohannX
User
Beiträge: 110
Registriert: Mittwoch 27. März 2019, 17:07

Das mit der Wahrheitstabelle klingt nach einem guten Ansatz, habe es hiermit probiert:

Code: Alles auswählen

df_Error1 = self.df_all[self.df_all["ID"] == self.ui.error_Base_1.text()]
            print(df_Error1.head())
            df_Error1_1 = df_Error1["DATA H"] == self.ui.error_flt_1.text()
            print(df_Error1_1.head())
            if df_Error1_1 == True:
               time_Error1 = self.df_all["Offset[s]"]
               values_Error1 = self.df_all["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)
Doch da bekomme ich folgende Fehlermeldung:

Code: Alles auswählen

    Start Date      Time  Offset[s]        ID    DATA H  DATA L
4   27.03.2019  17:18:26     0.0045  1100001x  800A7229       2
5   27.03.2019  17:18:26     0.0048  1100001x  800A7279       2
6   27.03.2019  17:18:26     0.0050  1100001x  800A7319       2
7   27.03.2019  17:18:26     0.0053  1100001x  800A73B9       2
21  27.03.2019  17:18:26     0.0845  1100001x  800A7229       2
4      True
5     False
6     False
7     False
21     True
Name: DATA H, dtype: bool
Traceback (most recent call last):
  File "ascFileReader.py", line 270, in export
    if df_Error1_1 == True:
  File "C:\Python3\lib\site-packages\pandas\core\generic.py", line 1556, in __nonzero__
    self.__class__.__name__
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
@ __blackjack__:
ja ich weiß wie ich diese Datensätze einzeln selektieren kann, das ist soweit kein Problem, falls ich daraus einen Schritt machen möchte, würde das so aussehen???

Code: Alles auswählen

df_Error1 = self.df_all[self.df_all["ID"], self.df_all[self.df_all["DATA H"] == self.ui.error_Base_1.text(), self.ui.error_flt_1.text()]]
Benutzeravatar
__blackjack__
User
Beiträge: 13112
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.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
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: 17754
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: 13112
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.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten