Seite 1 von 3

asc File Zeilen Suchen und entfernen

Verfasst: Freitag 2. August 2019, 12:42
von JohannX
Mein Problem besteht darin, dass in einer asc Datei Fehlerhafte Bereiche enthalten sind

Code: Alles auswählen

27.03.2019;17:18:26;000000470.243300;1100001x;800A6AC9;00000008;
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;
Jetzt möchte ich gern die asc Datei Zeile für Zeile einlesen und jede Zeile welche "ErrorFrames enthält gar nicht erst in die neue Variable speichern, oder einfach die Zeilen mit "ErrorFrames auszulassen.
Keine Ahnung was hier besser wäre.

Mein Gedanke war jetzt das mit einer for Schleife zu lösen.

Code: Alles auswählen

         df_all = pd.read_csv(self.file_asc)
         for lines in df_all:
            if lines != "ErrorFrames: 0 4702439 1 0 0 1":
               None
            else:
               neue_csv.append(lines)
Aber genaueres kann ich ihm Internet leider nicht finden, zumindest nichts was mein Problem betrifft.
Meine Python Kenntnisse reichen hier noch nicht so weit.

Dieses Video sah zwar vielversprechend aus
https://www.youtube.com/watch?v=2AFGPdN ... 9y&index=8
Aber es dürfte eher zu umständlich sein und konnte es auch nicht zusammenbringen.

Vielleicht hat jemand Erbarmen und Erleuchtet mich :)

Re: asc File Zeilen Suchen und entfernen

Verfasst: Freitag 2. August 2019, 12:50
von Sirius3
Du mußt die Zeilen vor dem Aufruf von read_csv herausfiltern.

Normalerweise macht man sowas mit einem Iterator.

Code: Alles auswählen

with open(self.file_asc) as lines:
    filtered_lines = (line for line in lines if not line.startswith('ErrorFrame'))
Irgendwie habe ich aber nichts gefunden, dass Pandas auch von Iteratoren lesen kann.

Re: asc File Zeilen Suchen und entfernen

Verfasst: Freitag 2. August 2019, 14:00
von __blackjack__
Man könnte das `comment`-Argument zum Filtern dieser Zeilen missbrauchen.

Re: asc File Zeilen Suchen und entfernen

Verfasst: Freitag 2. August 2019, 14:08
von Sirius3
@__blackjack__: das kommt aber nur mit einem Buchstaben klar. Wahrscheinlich kollidiert das, wenn ein `E` in einem der Hex-Werte vorkommt.

Re: asc File Zeilen Suchen und entfernen

Verfasst: Freitag 2. August 2019, 15:36
von __blackjack__
Dann würde ich die Zeilen einfach nach dem einlesen herausfiltern. Das ist ja recht deutlich identifizierbar was bei solchen Zeilen in der Datumsspalte landet. Oder man filtert die Datei erst einmal in ein `io.BytesIO`-Objekt und übergibt das dann der `read_csv()`-Funktion.

Re: asc File Zeilen Suchen und entfernen

Verfasst: Freitag 2. August 2019, 15:57
von ThomasL
wie wäre es hiermit:

Code: Alles auswählen

with open('data.csv') as file:
    skiprows = [i for i, line in enumerate(file) if line.startswith('Error')]

df = pd.read_csv('data.csv', sep=';', skiprows=skiprows)

Re: asc File Zeilen Suchen und entfernen

Verfasst: Freitag 2. August 2019, 19:14
von kbr
Oder so:

Code: Alles auswählen

from functools import partial
from io import StringIO
import pandas as pd

with open('data.csv') as fobj:
    buffer = StringIO('\n'.join(line.strip(';\n') for line in fobj if not line.startswith('ErrorFrame')))

df = pd.read_csv(buffer, sep=';', header=None, converters={4: partial(int, base=16)})

Re: asc File Zeilen Suchen und entfernen

Verfasst: Montag 5. August 2019, 09:49
von JohannX
kbr hat geschrieben: Freitag 2. August 2019, 19:14 Oder so:

Code: Alles auswählen

from functools import partial
from io import StringIO
import pandas as pd

with open('data.csv') as fobj:
    buffer = StringIO('\n'.join(line.strip(';\n') for line in fobj if not line.startswith('ErrorFrame')))

df = pd.read_csv(buffer, sep=';', header=None, converters={4: partial(int, base=16)})
Danke dein Code hat mir sehr geholfen!
Hab den Code leicht angepasst

Code: Alles auswählen

         with open(self.file_asc) as file:
            buffer = StringIO('\n'.join(line.strip(';\n') for line in file if not line.startswith('ErrorFrames')))
            print(buffer)

         self.df_all = pd.read_csv(buffer, sep = ";", skiprows = 5, skipinitialspace = True, converters = {'DATA L': partial(int, base = 16)})
Damit ist der Montag gerettet :)

Ein kleines Problem wäre da noch und zwar, ich lese eine xml Datei aus und die Werte welche zusammen gehören werden in eine liste gespeichert.
Jetzt möchte ich einen Wert mit der Formel welche in der liste gespeichert ist Berechnen.

Funktioniert:

Code: Alles auswählen

values_Name_1 = df_Name_1["DATA L"].apply(lambda v: v*(5/1024)*9.980487805)
Funktioniert nicht:

Code: Alles auswählen

values_Name_1 = df_Name_1["DATA L"].apply(lambda v: self.liste[0][1])
Liegt daran dass es als str gepeichert wird und wegen dem v* kann es nicht in int umgewandelt werden

gibt es dafür eine Möglichkeit dies zu Bereinigen?

Re: asc File Zeilen Suchen und entfernen

Verfasst: Montag 5. August 2019, 10:20
von Sirius3
Ein "Funktioniert nicht" ist eine schlechte Fehlerbeschreibung. Bei Deinem apply benutzt Du v ja gar nicht, und woher kommt das `self`?
Gib ein komplettes Beispiel, damit man Dir helfen kann.

Re: asc File Zeilen Suchen und entfernen

Verfasst: Montag 5. August 2019, 10:23
von __deets__
Was macht deiner Meinung nach apply? Woher kommt das v als Argument fuer das Lambda, und wo genau ist das in deinem zweiten Code-Snippet der "nicht funktioniert"?

Re: asc File Zeilen Suchen und entfernen

Verfasst: Montag 5. August 2019, 10:40
von JohannX
Das ist einmal der Code der dafür verantwortlich ist:

Code: Alles auswählen

      self.liste = []
   def xml(self): # xml File auswählen und im InfoFeld anzeigen lassen
      self.file_xml, _  = QFileDialog.getOpenFileName(self, 'Open file', 'c:\\',"Image files (*.flipxEnvSig)")
      self.ui.Info_xml.setText(self.file_xml)
      tree = ET.parse(self.file_xml)
      root = tree.getroot()
      for EnvSigConfigRow in root.iterfind("rows/EnvSigConfigRow"):
         self.liste.append((EnvSigConfigRow.findtext('name'), EnvSigConfigRow.findtext('formula'), EnvSigConfigRow.findtext('canId')))

   def export(self):
      if self.file_xml is None:
         None

      if self.file_asc is None:
         None

      if self.file_export is None:
         None

      else:
         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)

         if self.counter >= 1:
            df_Name_1 = self.df_all[self.df_all["ID"] == self.liste[0][2]]
            time_Name_1 = df_Name_1["Offset[s]"]
            values_Name_1 = df_Name_1["DATA L"].apply(lambda v: self.liste[0][1])

Das apply fügt etwas hinzu welches in der () steht
Das v als Argument habe ich vom vorherigen Code übernommen, jedoch war dort x und die Formel war x*(5/4095)*5.896

Re: asc File Zeilen Suchen und entfernen

Verfasst: Montag 5. August 2019, 10:51
von __deets__
Das das apply etwas hinzufuegen wuerde ist ein bisschen sehr salopp und spricht nicht dafuer, dass du das begriffen hast, was da wirklich passiert. apply bekommt kein Argument, das dann "hinzugefuegt" wird (was auch immer das sein soll. Addition?). Sondern es bekommt eine Funktion oder allgemeiner ein Callable, und das muss ein Argument bekommen. Und einen Rueckgabewert liefern. Und dann wird dieses Callable auf JEDES Elemen in der Spalte angewandt, und der Wert vorher mit der Rueckgabe ersetzt.

Ein ...apply(lambda v: 10) ersetzt also alle Werte einfach mit 10. Egal was sie vonher waren. Ein ...apply(lambda v: v * 2) ersetzt sie mit dem Doppelten. Und .apply(lambda v: v*(5/1024)*9.980487805) ersetz sie eben mit v * einem Faktor der etwas kompliziert geschrieben ist.

Und was macht ..apply(lambda v: self.liste[0][1]) deiner Meinung nach dann, und wie verhaelt sich das zu dem, was da vorher stand?

Re: asc File Zeilen Suchen und entfernen

Verfasst: Montag 5. August 2019, 11:01
von Sirius3
Eingerückt wird mit 4 Leerzeichen pro Ebene, nicht 3. Die `None` in den if-Blöcken sollen wohl `pass` sein, und besser ein `if self.file_xml is not None and self.file_asc is not None and self.file_export is not None:`.
`liste` ist ein sehr schlechter Name für eine was auch immer, denn das wird aus dem Namen nicht klar. Was soll das _1 an den ganzen Variablennamen? Und warum hast Du eine Liste, wenn die nur das erste Element interessiert?
Was versuchst Du denn mit dem `apply´ zu erreichen?

Re: asc File Zeilen Suchen und entfernen

Verfasst: Montag 5. August 2019, 12:10
von JohannX
Ich rücke da immer mit einem Tabulator ein, ist bei Python kein Problem 8)
Und was macht ..apply(lambda v: self.liste[0][1]) deiner Meinung nach dann, und wie verhaelt sich das zu dem, was da vorher stand?
In self.liste[0][1] ist die Formel v*(5/1024)*9.980487805 enthalten, da die Formel genau wie Name und ID vorher aus einer xml Datei ausgelesen worden sind. DIese Werte wurden dann in eine Liste gespeichert.

Wenn ich den Code jetzt so ausführe, wird die Formel als Wert eingesetzt und somit wird beim Ploten eine schöne gerade Linie ausgegeben.

Gibt es bei Python eine Funktion welche mir noch nicht bekannt ist um dieses Problem zu lösen?
Also etwas dass die Formel vielleicht ausrechnet ohne das v zu berücksichtigen?

Re: asc File Zeilen Suchen und entfernen

Verfasst: Montag 5. August 2019, 12:18
von Sirius3
@JohannX: nein, Dein Editor wandelt Tab in 3 Leerzeichen um, das solltest Du auf 4 Leerzeichen umstellen.

Wenn in der Liste ein String steht, der aussieht wie eine Formel, dann mußt Du diesen String erst in etwas umwandeln, mit dem Python rechnen kann. Welche Syntax kann so eine Stringformel haben? Woher weißt Du, welche Variable die Formel enthält?

Re: asc File Zeilen Suchen und entfernen

Verfasst: Montag 5. August 2019, 12:19
von JohannX
Sirius3 hat geschrieben: Montag 5. August 2019, 11:01 Eingerückt wird mit 4 Leerzeichen pro Ebene, nicht 3. Die `None` in den if-Blöcken sollen wohl `pass` sein, und besser ein `if self.file_xml is not None and self.file_asc is not None and self.file_export is not None:`.
`liste` ist ein sehr schlechter Name für eine was auch immer, denn das wird aus dem Namen nicht klar. Was soll das _1 an den ganzen Variablennamen? Und warum hast Du eine Liste, wenn die nur das erste Element interessiert?
Was versuchst Du denn mit dem `apply´ zu erreichen?
Ich versuche mit .apply einen Wert welcher sich mit (lambda v : self.liste[0][1]) befindet zu einem anderen Wert welcher in values_Name_1 = df_Name_1["DATA L"] vorhanden ist zu multiplizieren, sodass sich beim Ploten des gesamten projektes ein Diagramm erstellen lässt mit dem man Arbeiten kann.

Das "liste" ein schlechter Name ist ist ja auch in Ordnung. Deshalb habe ich ihn nun geändert "liste_in_welcher_die_xml_File_ausgelesen_und_die_notwendigen_Daten_gespeichert_werden"
Ist nun besser Nachvollziehbarer als vorhin 8)

Re: asc File Zeilen Suchen und entfernen

Verfasst: Montag 5. August 2019, 12:20
von __blackjack__
@JohannX: Du rückst nicht mit einem Tabulator ein. Du verwendest vielleicht die Tabulator-*Taste*, die fügt bei Dir aber keinen Tabulator ein, sondern einscheinend drei Leerzeichen. Und das sollten halt *vier* statt drei sein.

In ``self.liste[0][1]`` ist keine Formel gespeichert, sondern eine Zeichenkette. Was da also steht ist ``.apply(lambda v: 'v*(5/1024)*9.980487805'`` was versucht jeden Wert in der Spalte durch die Zeichenkette 'v*(5/1024)*9.980487805' zu ersetzen. Da der Typ der Spalte aber `int` ist, wird versucht die Zeichenkette 'v*(5/1024)*9.980487805' in eine Zahl zu wandeln – was nicht geht, weil die Zeichenkette keine Darstellung einer Zahl enthält.

Re: asc File Zeilen Suchen und entfernen

Verfasst: Montag 5. August 2019, 12:29
von JohannX
Sirius3 hat geschrieben: Montag 5. August 2019, 12:18 @JohannX: nein, Dein Editor wandelt Tab in 3 Leerzeichen um, das solltest Du auf 4 Leerzeichen umstellen.

Wenn in der Liste ein String steht, der aussieht wie eine Formel, dann mußt Du diesen String erst in etwas umwandeln, mit dem Python rechnen kann. Welche Syntax kann so eine Stringformel haben? Woher weißt Du, welche Variable die Formel enthält?
Laut dem Editor Studio Visual Code sind beim Tab Size: 4 eingestellt.
Als Syntax kenne ich "str, int, float" falls du das meinst

Re: asc File Zeilen Suchen und entfernen

Verfasst: Montag 5. August 2019, 12:31
von JohannX
__blackjack__ hat geschrieben: Montag 5. August 2019, 12:20 @JohannX: Du rückst nicht mit einem Tabulator ein. Du verwendest vielleicht die Tabulator-*Taste*, die fügt bei Dir aber keinen Tabulator ein, sondern einscheinend drei Leerzeichen. Und das sollten halt *vier* statt drei sein.

In ``self.liste[0][1]`` ist keine Formel gespeichert, sondern eine Zeichenkette. Was da also steht ist ``.apply(lambda v: 'v*(5/1024)*9.980487805'`` was versucht jeden Wert in der Spalte durch die Zeichenkette 'v*(5/1024)*9.980487805' zu ersetzen. Da der Typ der Spalte aber `int` ist, wird versucht die Zeichenkette 'v*(5/1024)*9.980487805' in eine Zahl zu wandeln – was nicht geht, weil die Zeichenkette keine Darstellung einer Zahl enthält.
Danke, das war jetzt verständlich für mich, somit muss ich die ' ' wegbekommen :wink:

Re: asc File Zeilen Suchen und entfernen

Verfasst: Montag 5. August 2019, 12:40
von Sirius3
Nein, Du hast ja irgendwoher dieses XML. Und darin ist sind Formeln, und diese müssen ja irgendeiner Syntax folgen. Hast Du eine Beschreibung des XML-Formats?

Und nein, Du mußt nicht die '' wegbekommen, sondern den String parsen, das heißt, in eine Form bringen, mit der Du rechnen kannst. Dazu müßte man aber wissen, nach welcher Syntax diese Formeln beschrieben sind.