Announcement

Collapse
No announcement yet.

C# Ausreißer aus Punktwole elemenieren

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • C# Ausreißer aus Punktwole elemenieren

    hallo,

    ich habe eine datei (txt) mit mehreren tausend punkten die wie folgt aufgebaut

    ist:

    x y z
    22323,83 443453,25 7,93
    23356,21 342173,25 8,12

    usw..

    (die abstände sind tabs in dem file - keine leerzeichen)
    so diese datei möchte ich so effizient wie möglich einlesen. da sie sehr gross
    ist dauert es leider mit dem streamreader was ich kenn sehr lange
    da kommen wir auch schon zu meiner ersten frage:

    - weiss jemand eine effiziente Lösung um ziemlich große dateien einlesen zu

    können ? (100000 zeilen und mehr)
    dabei ist mir vorallem die letzte Spalte (z) wichtig, denn eigentlich brauch ich
    zum auswerten nur diese. wo wir auch schon bei meiner 2. frage wären:

    - gibt es eine möglichkeit genau nur diese spalte auszuwerten ?

    im endeffekt sollen nämlich die werte in ein neues file geschrieben werden,
    jedoch befreit von ausreißern aber wieder in der x y z form (die x und y werte
    werden und sollen auch nicht berührt werden).

    meine dritte und letzte frage lautet ob jemand eine idee hat wie ich am besten

    die ausreißer eleminiere und woran ich das festmach. ich dachte da so als erstes an mitelwert, standartabweichung und median (wobei ich auch noch nicht weiss wie man diesen programmiertechnisch bestimmt )
    evtl mit min max arbeiten, aber wie setze ich da am besten die grenzen ?

    die ausgabe datei sollte im endeffekt die gleichen konventionen besitzen (also

    tabulator und kommata, txt usw)

    zusammengefasst:

    1. effiziente möglichkeit zum einlesen großer dateien
    2. direkt eine gewisse spalte auswerten
    3. ausreißer eleminieren nach einem bestimmten algorithmus

    vielleicht hat jemand von euch einen rat, snippet oder pseudocode parat der eines oder am besten alle probleme lösen kann.

    das wäre super. danke im vorraus!

  • #2
    100000 Zeilen und mehr sind natürlich ein Hammer. Was wirklich schnell geht, weiß ich deshalb nicht; aber ich habe ein paar Vorschläge. Das Hauptproblem dürfte weniger das Einlesen und Speichern der Datei sein, sondern die Analyse aller Zeilen: Die "Ausreißer" findest Du ja nur dadurch, dass jede Zeile einzeln geprüft wird. Außerdem kosten das Umspeichern und Aufteilen von Strings viel Zeit.

    - weiss jemand eine effiziente Lösung um ziemlich große dateien einlesen zu können ?
    Variante 0 mit StreamReader vergesse ich gleich wieder, weil das mit Variante 1 eleganter gelöst wird.
    Variante 1: als String-Array einlesen:
    Code:
    string[] contents = File.ReadAllLines("MyFile.txt");
    Variante 2: als String einlesen:
    Code:
    string content = File.ReadAllText("MyFile.txt");
    Variante 3: als DataTable einlesen; diese Lösung empfehle ich wegen der Prüfung der Ausreißer. Siehe dazu ConnectionStrings: Textfiles für OleDb und "Delimited Columns", ggf. zusammen mit Schema.Ini

    Schneller ist vielleicht der CsvReader. Aber das ist nur der CsvReader, noch nicht der CsvWriter.

    - gibt es eine möglichkeit genau nur diese spalte auszuwerten ?
    Bei Variante 1 und 3 ist das unmittelbar klar: Index = Anzahl-1. Bei Variante 2 kannst Du vom Ende her zurückgehen, bis Du auf "\r" oder "\n" oder Environment.NewLine triffst, und dann den Abschnitt mit SubString herausholen.

    wie ich am besten die ausreißer eleminiere
    Mit statistischen Verfahren habe ich mich eigentlich nie beschäftigt; das musst Du Dir selbst ausdenken. Damit die Werte getrennt zur Verfügung stehen, empfehle ich die DataTable. Dann kannst Du alle "unpassenden" Zeilen löschen und am Schluss die Datei auf dem gleichen Weg speichern, wie Du sie gelesen hast.

    Beim Arbeiten über Strings kämen das zeitaufwändige String.Split sowie Double.TryParse hinzu; alle "passenden" Zeilen müssten zudem noch in eine List<string> kopiert werden - das wird alles viel umständlicher als die Lösung mit DataTable.

    Ich hoffe, ich konnte etwas weiterhelfen. Jürgen

    PS. Warum wird der Standard eigentlich immer mit der Standarte oder Standkunst (= Stand-art) verwechselt?

    PS2. Was ist eigentlich "Punktwole"? Und "eliminieren" wird über die Forumssuche leichter gefunden.

    Comment


    • #3
      @Jürgen Thomas

      danke für die tipps. die sind sehr sehr hilfreich. ich glaube die variante 3 scheint am effektivsten zu sein.

      zwecks der auswertung habe ich mir schon ein paar gedanken gemacht diese statistisch zu ermitteln. auch wenn es hier vielleicht uninteressant erscheint, habe ich mir mal den algorithmus von RANSAC angeschaut und den ausreißertest von Grubbs

      und sorry für meine rechtschreibfehler hab zu schnell getippt und übersehen

      Comment


      • #4
        noch eine frage zu DataTable:

        muss ich dafür den MSServer (oder wie immer der heisst) haben/starten oder dergleichen ? die xyz werte stammen nämlich aus einer shape datei und diese kann ich auch als .mdb exportieren was ja eigentlich kein problem sein sollte zu handeln. nur weiss ich jetzt nicht ob ich so direkt die reine .mdb datei ansprechen kann (ist nur eine einzige tabelle ohne beziehungen usw)??

        Comment


        • #5
          Hallo,

          den MS-SQL Server brauchst Du unter keinen Umständen. DataTable ist eine Klasse für eine Datenmenge ausschließlich im Arbeitsspeicher. Woher die Daten kommen, ist zunächst völlig gleichgültig.

          Zum Einlesen und Speichern der Daten braucht man geeignete Programme oder Programmteile; dies machen unter ADO.NET die passenden DbProvider - für csv (wie oben gesagt) Odbc oder (besser) OleDb. mdb klingt eher nach Access-Format; dafür ist ebenfalls OleDb zuständig, siehe den o.g. Link zu ConnectionStrings.

          Jürgen

          Comment


          • #6
            Originally posted by acid0000 View Post


            im endeffekt sollen nämlich die werte in ein neues file geschrieben werden,
            jedoch befreit von ausreißern aber wieder in der x y z form (die x und y werte
            werden und sollen auch nicht berührt werden).


            3. ausreißer eleminieren nach einem bestimmten algorithmus
            Hi acid0000.
            ich beschäftige mich auch mit ähnlichem Problem (3). (DA)
            es geht um oberflächenanalyse von blöcken.

            Schau doch mal das verfahren Integration und Vorschub an
            und folglich
            Regressionsanalyse
            Geht um mittelwertbestimmung und anschließender ausfilterung der BadValues

            Das Problem mit Regressionsanalyse habe ich es so gelöst:

            Code:
            //filterung der bad values 
            //d.h.  nur die mittleren werte berücksichtigen,  AUSREIßER ausschließen  
            schaud dir die werte in Excel an, da wird meist alles klarer
            //1. liste sortieren
            myList.Sort();
            
            //2. die ersten 30% und die letzten 40% nicht beachten(filtern) 
            egal ob diese gut oder schlecht sind nur das mittel ist wichtig.
            
            for (int i = (int)(myList.Count * 0.3); i < (int)myList.Count * 0.60 - 1; i++)
            {
                summe += myList[i];
                counterAnzahl++;
            }
            idealWert = summe / counterAnzahl;
            am ende hast du die ideale mitte von den Y-Werten (Z-Werten).
            und das ist schon das absolute mittel/ Idealwert

            Anschließend brauchst du die Abweichenden Werte zu bearbeiten.

            OK. Noch fragen? Stehe gerne zu verfügung.

            Comment

            Working...
            X