Datatable, mathematische Berechnung für AVG, Min, Max und Standardabweichung

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von P8310.

    Datatable, mathematische Berechnung für AVG, Min, Max und Standardabweichung

    Hallo zusammen,

    Jetzt brauch ich eure Hilfe. Ich benötige für ein Chart (+- 3 Sigma) folgende mathematische Berechnung.

    Je ROW: den Mittelwert, MIN, Max und Standardabweichung

    Datengrundlage ist ein Datatable das je Testversuch eine Spalte besitzt und maximal 650 Tests(Spalten) beinhaltet.

    (38,2080078125 39,794921875 48,88916015625 51,025390625 61,21826171875 35,82763671875 56,57958984375 72,32666015625 28,74755859375 45,654296875 41,68701171875.....)

    Nun müsste für die Berechnung die gesamte Row durchlaufen werden um AVG, Min, Max und Standardabweichung zu erhalten. Und hier scheitere ich aktuell.

    Eventuell hat wer eine Idee dieses zu ermitteln.

    Vielen Lieben dank
    Eine Spalte ist ein Testversuch mit je 1000 Messwerte.

    wie binde ich hier das dt ein? beziehungsweise eine Row der Datatable.

    VB.NET-Quellcode

    1. Dim grades As New List(Of Integer)(New Integer() {78, 92, 100, 37, 81})
    2. Dim avg As Double = grades.Average()

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „P8310“ ()

    Wäre es nicht sinnvoller 2 DataTables zu haben? Eine Versuche-Table mit der Spalte ID und Name(?) und zum anderen eine Messwert-Table, bei der eben als Spalten sind: ID, Messergebnis, VersuchsID
    Dann kann man das auch im tDS-Designer anlegen, kann somit typisiert arbeiten und dann auch die Messwerte eines Versuchs per Versuch(x).GetMesswertRows() herholen und dann ggf. per .Select() oder anderen LINQ-Geschichten - wie petaod bereits schrieb - arbeiten.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    VaporiZed schrieb:

    2 DataTables
    Das wäre in der Tat der Normalform-Ansatz, mit dem man als Datenbänker arbeiten würde.

    Ich habe allerdings die Vermutung, dass die Messwerte original als CSV vorliegen und mittels OleDB in eine Datatable verwandelt werden.
    So jedenfalls kenne ich das allgemein verbreitete Messingenieur-Vorgehen.
    Für den "richtigen" Ansatz müsste man da eine Importroutine schreiben, die die Daten erst mal in Normalform bringt.

    Aber vielleicht verrät uns @P8310, wie die Daten tatsächlich ins Programm kommen.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    Hallo zusammen,

    Richtig pedaot, es sind CSV Dateien die wie folgt gelesen werden.

    VB.NET-Quellcode

    1. Dim dt As New DataTable
    2. Dim oConn As OleDb.OleDbConnection
    3. Dim oAdapter As OleDb.OleDbDataAdapter
    4. Dim sFile As String = Pfad
    5. Dim sTable As String = Liste
    6. Dim sConn As String = "Provider=Microsoft.Jet.OLEDB.4.0;" &
    7. "Data Source=" & sFile & ";" &
    8. "Extended Properties=Excel 8.0;"
    9. oConn = New OleDb.OleDbConnection(sConn)
    10. oAdapter = New OleDb.OleDbDataAdapter(
    11. "SELECT * FROM [" & sTable & "$]", oConn)
    12. Try
    13. oAdapter.Fill(dt)
    14. Catch ex As Exception
    15. MsgBox(ex.Message)
    16. Box1.BackColor = Color.Red
    17. Finally
    18. oConn.Close()
    19. End Try
    Vorausgesetzt ich habe dich richtig verstanden, dass alle deine Werte in einer Zeile im Datatable stehen, müsste das hier funktionieren:

    Leg dir folgende Klasse an:

    VB.NET-Quellcode

    1. Public Class Messwert
    2. Public Property Werteliste As List(Of Double)
    3. Public Property MinWert As Double
    4. Public Property MaxWert As Double
    5. Public Property Average As Double
    6. Public Property Standardabweichung As Double
    7. End Class


    Dann kannst du mit dieser Methode deine Daten laden:

    VB.NET-Quellcode

    1. Private Function Messwerte(dt As DataTable) As List(Of Messwert)
    2. Dim MesswertListe As New List(Of Messwert)
    3. For Each Column As DataColumn In dt.Columns
    4. Dim Werte = CStr(dt.Rows(0)(Column.ColumnName)).Split(CChar(" ")).Select(Function(n) CDbl(n)).ToList
    5. Dim MW As New Messwert With {.Werteliste = Werte, .MinWert = Werte.Min(), .MaxWert = Werte.Max, .Average = Werte.Average}
    6. MW.Standardabweichung = Math.Sqrt((From x In MW.Werteliste Select (x - MW.Average) ^ 2).Average)
    7. MesswertListe.Add(MW)
    8. Next
    9. Return MesswertListe
    10. End Function


    Dass die Tabellenstruktur suboptimal ist, brauche ich vermutlich nicht erwähnen. Code ist nicht getestet, da ich ehrlich gesagt keine Testdaten in dieser Struktur vorliegen habe.


    Ein Computer wird das tun, was du programmierst - nicht das, was du willst.
    Oh stark! vielen lieben dank. Muss noch etwas angepasst werden. Aber das sollte klappen. Habe ein Bild angehangen wie die Daten im DT stehen. Und wie beschrieben, um Sigma kurve zu zeichnen brauch ich je Timestep(Spalte2) 0; 0,1;0,2...den min,max, avg, und Standardabweichung.
    Bilder
    • BZ.png

      52,16 kB, 1.374×816, 147 mal angesehen
    Dateien
    • Beispiel.xlsx

      (133,5 kB, 237 mal heruntergeladen, zuletzt: )

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „P8310“ ()

    Ja dann ist das ja wirklich easy. Die Werte brauchen ja gar nicht mehr aufgeteilt werden. Ersetze einfach folgende Zeile:

    VB.NET-Quellcode

    1. Dim Werte = CStr(dt.Rows(0)(Column.ColumnName)).Split(CChar(" ")).Select(Function(n) CDbl(n)).ToList


    Mit dieser Zeile

    VB.NET-Quellcode

    1. Dim Werte = (From x In dt.Rows Select CDbl(TryCast(x, DataRow)(Column.ColumnName))).ToList


    Dann solltest du eine saubere Werteliste erhalten.

    Wenn du mit Option Strict Off arbeitest (Standardeinstellung), kannst du den Code natürich noch schlanker gestalten. Viele hier im Forum raten dazu, diese Option einzuschalten, deshalb poste ich hier generell nur Code, der mit Option Strict On funktioniert. Hilft ungemein bei der Fehlererkennung, aber bleibt natürlich dir überlassen ob du die Option einschaltest oder nicht.


    Ein Computer wird das tun, was du programmierst - nicht das, was du willst.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Yanbel“ ()

    Um die Werte je Zeile zu erhalten, lässt man die Schleife über die Zeilen laufen.

    VB.NET-Quellcode

    1. Private Function Messwerte(dt As DataTable) As List(Of Messwert)
    2. Dim MesswertListe As New List(Of Messwert)
    3. For Each Row As DataRow In dt.Rows
    4. Dim Werte As List(Of Double) = (From x In dt.Columns Where TryCast(x, DataColumn).ColumnName.Contains("Test") Select CDbl(Row(TryCast(x, DataColumn)))).ToList
    5. Dim MW As New Messwert With {.Werteliste = Werte, .MinWert = Werte.Min(), .MaxWert = Werte.Max, .Average = Werte.Average}
    6. MW.Standardabweichung = Math.Sqrt((From x In MW.Werteliste Select (x - MW.Average) ^ 2).Average)
    7. MesswertListe.Add(MW)
    8. Next
    9. Return MesswertListe
    10. End Function
    Super vielen dank, jetzt geht es. Außer die Standardabweichung ist falsch.

    Also rein Rechnerisch ist es ja richtig: (Wurzel aus AVG) ^2. Das Passt auch vom wert her. Rechnet Excel Mit der Formel (STABW) anderes?

    ----Okay hab es gefunden. EXCEL (STABW) ist eine Schätzung ausgehend von Stichproben und (Math.Sqrt((From x In MW.Werteliste Select (x - MW.Average) ^ 2).Average)) aus die Grundgesamtheit.

    An alle VIELEN Lieben Dank euch.


    Bilder
    • Vergleich_1.png

      30,15 kB, 1.331×362, 114 mal angesehen

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „P8310“ ()