Gleitenden Mittelwert oder gleitenden Median berechnen

Hallo Freunde

es kommt ja öfter mal vor das man aus anfallenden Daten den gleitenden Mittelwert oder den Median berechnen möchte.
d.h. den Mittelwert (oder Median) aus den Werten welche in den letzten x Sekunden gelogged wurden.
Nur mit Variablen ist das ein rechter Krampf und nicht flexibel, aber wir haben ja unsere Datenbank.
Die nackten AC_Getxxx Funktionen geben das allerdings in dieser Form auch nicht nicht her.

Hier also zwei kleine Funktionen die dieses erledigen:

<?
$IDArchiveHandler = 22801 /*your Archive Handler ID*/;
$varId = 37190 /*Var Id you want to examine*/;
$interval = 50; /*Timespan in seconds for Mean/Median Calculation*/;
$default = 0; /* default value in case no data capturd */

echo "Mean: ".getMean ($IDArchiveHandler,$varId,$interval,$default);
echo chr (13). chr (10);
echo "Median: ".getMedian ($IDArchiveHandler,$varId,$interval,$default);



function getMean ($IDArchivehandler,$varId,$log_interval,$default) {
$logData = AC_GetLoggedValues ($IDArchivehandler, $varId, time()- $log_interval,time(),-1);
if (count($logData) <1) return $default;
foreach ($logData as $key => $data)
{
    $value[$key] = $data['Value'];
}
return array_sum($value)/count($value);
}

function getMedian ($IDArchivehandler,$varId,$log_interval,$default) {
$logData = AC_GetLoggedValues ($IDArchivehandler, $varId, time()-$log_interval,time(),-1);
if (count($logData) <1) return $default;
foreach ($logData as $key => $data)
{
    $value[$key] = $data['Value'];
}
asort($value);
return $value[count($value)/2];
}
?>

edit 05.12.2014 : Fehlerbehandlung eingebaut, wenn im Zeitraum keine Daten gelogged wurden

Verwendung ist wohl selbsterklärend
Gruß
bb

Danke für das Skript, sieht gut aus und macht was es soll :slight_smile:

Hatte bisher dieses hier verwendet:

…und das hat mir teilweise komische Werte ausgegeben (vlt. war ich aber auch zu doof :smiley: ).

Hatte beim 1. Aufruf vom Skript (Zeitspanne 30 Sek.) einen Fehler in Zeile 18 und Folgefehler, dass das array_sum was anderes erwarten würde und keine Ahnung, dann hab ich die Zeitspanne erhöht auf 900, dann lief das Skript. Dann die Zeitspanne zum Testen auf 1 gestellt, funktioniert trotzdem. Seltsam :smiley: Egal, mehrere Variablen getestet und es funktioniert :slight_smile: Danke!

Grüße,
Chris

Eben hatte ich wieder einen Fehler, Variable geändert, Skript mit Zeitspanne 60 Sekunden ausgeführt, Fehler, mehrmals ausgeführt und beim 3. oder 4. Mal ausführen wurden mir auf einmal Werte ausgespuckt und jetzt läuft es wieder… Hmmm…

Fehler:


Notice:  Undefined variable: value in C:\IP-Symcon\scripts\30198.ips.php on line 18

Warning:  array_sum() expects parameter 1 to be array, null given in C:\IP-Symcon\scripts\30198.ips.php on line 18

Notice:  Undefined variable: value in C:\IP-Symcon\scripts\30198.ips.php on line 18

Warning:  Division by zero in C:\IP-Symcon\scripts\30198.ips.php on line 18
Mean: 

Warning:  asort() expects parameter 1 to be array, null given in C:\IP-Symcon\scripts\30198.ips.php on line 27
Median: 

Jetzt hab ich noch mehrmals das Skript ausführen lassen und immer mal den Interval geändert und auf einmal lief es wieder nicht mehr, dann kurz gewartet und dann nach ein paar weiteren Versuchen wurden dann wieder Werte ausgegeben :confused: Als würde der Archiv-Handler dicht machen und das Skript bekommt keine Werte und deswegen der Fehler…seltsam…

Servus

Sehr merkwürdig.Es läuft heir seit 2 tagen.
Ich rufe es für 4 variablen im 50sec Intervall auf. Soweit hab ich noch kein Fehlverhalten beobachtet.

Wär natürlich möglich eine Abfrage einzubauen damit es zumindest keinen Fehler gibt, im falle das vom Archive Handler nix zurückkommt.

gruß
bb

Vermutlich kommt auch kein Fehler, wenn man das „normal“ benutzt :smiley:

Man könnte etwas einbauen um den Fehler abzufangen, dass sich ein Timer stellt und dann nach X Sekunden erneut versucht wird die Werte zu holen. Das vlt. 3 Mal und wenn es bis dahin nicht geklappt hat, dann ERROR und Ende… Aber das kann ja jeder für sich machen :slight_smile:

Grüße,
Chris

Bei diesem hatte ich ein ähnliches Problem (Division by Zero), wenn Änderungen erfolgt sind oder gerade nicht kontinuierlich Werte vorhanden waren. Es ließ sich durch einfügen von

//echo "N-Werte: ".$anzahl. "
";
If ($anzahl == 0) {
      $anzahl = 1;
}

recht einfach umgehen.

Beim Spielen mit bb’s Skript kann ich das von @Bayaro beschriebene Verhalten bestätigen. Wenn nach kurzer Zeit kontinuierlich Werte vorhanden sind, läuft`s absolut schmerzfrei.

Ich frage mich aber gerade ob der Archive Handler ein Problem hat oder das normales Verhalten ist?

Cheers
/Jens

OK,OK wenn keine Daten da sind, kann man auch nix berechnen.:rolleyes:

Hab euch eine passende Abfrage und Defaultwert eingebaut.
bitte von erstem Post neu kopieren.

Hatte bei mir nix bemerkt, da meine Daten von 1Wire kommen und immer hundertprozentig vorhanden sind.

viel Spass
bb

Kleines Detail-Genörgel Schpässle

Beim Ermitteln des Durchschnitts sollte man darauf achten, dass die Messintervalle gleich sind, ansonsten kommt Murks raus (bzw. sollte man dann mit gewichtetem Durchschnitt arbeiten)

Beim ermitteln des Medians ist es besser, mit ungerader Anzahl (und einer möglichst hohen Anzahl => Statistiker sagen: mindestens 30 Messwerte) von Messwerten zu arbeiten.

Hier mal eine Median-Funktion, die etwas fehlertoleranter ist :wink:


function median($array = array())
{
    $count = count($array);
    if($count <= 0)
    {
       return false;
    }
    sort($array, SORT_NUMERIC);
    
    if($count % 2 == 0)
    {
       return ($array[floor($count/2)-1] + $array[floor($count/2)]) / 2;
    }
    else
    {
       return $array[$count/2];
    }
}

Servus Schnecke

… hast dafür eine Quelle ?
Beruflich verwende ich den Median recht oft, von einer Mindestmesswertanzahl hab ich bis jetzt nichts gehört. Was aber nix heisen muß.

Kommt aber wohl eher darauf an was man erreichen will:

  • Mittelwert für kontinuierliche ausreißerbereinigte Daten
  • Median für Daten wo mit Ausreißern gerechnet werden muß.

gruß
bb

ja, die Quelle ist mein Haus- und Hof-Mathematiker, mit dem ich regelmäßig meine Projekte durchkaue (na ja, jetzt nicht mehr so oft :D)
Und Wenn Du SixSigma-Kurse, insbesondere Statistik eingeflößt bekommst, sollte das auch ein Thema sein :wink:
Grundsätzlich gilt: je mehr Messwerte in der Grundgesamtheit, desto belastbarer der Mittelwert oder Median.

Wie Du schon sagst: man muss wissen, was man erreichen will. Am besten schaut man sich die Ergebnisse aus den Messreihen nach beiden Modellen an und entscheidet dann, was besser zur gewünschten Aussage passt.

Six-Sigma, natürlich - Bäähhhh
Ich mein, das hat natürlich schon alles seine Berechtigung - Bauchgefühl kann aber durch nichts ersetzt werden - behaupte ich - Theorie und Q- Abteilung sagt was anderes.

bzgl. des Mathematikers. Klar, er hat absolut recht, keine Frage.
Wenn man die Daten als gegeben vorliegen hat (das haben Mathematiker im allgemeinen) ist das klar.
Wenn aber jedes Bit und msec Datenerfassung Geld kostet dann muß man mit den Füßen am Boden bleiben und Kompromisse machen.

Umgelegt auf IPS Verhältnisse: Wenn ich vielleicht nur alle 10sec loggen kann(irgendwie ein realistischer Wert) , aber trotzdem einen 1min Mittelwert möchte, dann bleibt mir halt nix anderes übrig als mit statistisch weniger aussagekräftigen Parametern zu hantieren.
Solange man weiß was man tut kein Problem.

mit statistischen Grüßen
bb

klar, immer mit Augenmaß! Und wenn man nicht genug Messdaten hat, muss man halt Kompromisse machen. Andersrum: wenn genug Messdaten vorliegen, sollte man soviel wie nötig nutzen. Sehe mal die Zahl 30 als anstrebsame Hausnummer, ab der man nicht mehr viel falsch machen kann.

Doof wäre hingegen, wenn ich ne stat. Analyse verkaufe, hinter der 4 Meßwerte liegen (und keiner weiß es) und mir auch noch einrede, es wäre alles perfekt :wink:

Und einen Prozess nur nach Mittelwert oder Median beurteilen zu können (wie schon mal der ein oder andere Quality-Experte) ist genau so hirnrissig

100% ack, aber die Zahl „30“ in den Raum zu stellen ist zu weit vereinfacht.
Das muß immer im Kontext mit der Probengröße bzw. im Falle von zeitlicher Abhängigkeit von der zeitlichen Varianz der Messergebnisse gesehen werden.

Ein Beispiel: Bei uns (in der Firma, sicherheitskritische Bausteine im Automobilbereich) ist die Standardfrage: " Wie viele Teile muß ich messen (jede Messung ist teuer) um eine eine verlässliche Aussage übe die Qualität treffen zu können.
Die Mathematiker hatten sich mal auf „200“ geeinigt .
Nun, eine Losgröße (Produktionseinheit) kann zwischen 50 und 100000 Bauteilen schwanken.
Was tun ? Wie du siehst ist es zu wenig nur eine Zahl in den Raum zu stellen.

never stop thinking
bb

ja genau, so ist es! Ich muss immer den Kontext im Auge behalten und verstanden haben, ob es reicht, ein „Problem“ mit 2 oder 20 Kennzahlen zu beschreiben bzw. ob ich mit 10 oder 100 Messwerten einer Messreihe hinkomme, um ein vernünftiges Verhältnis zwischen Aussagekraft/Aufwand und Belastbarkeit/Genauigkeit der resultierenden Aussage zu erreichen.

Paßt !
bb

Um nochmal auf das Thema zurück zu kommen :slight_smile:
…gibt es jetzt ein Problem mit dem Archive-Handler oder bin ich zu doof das Skript richtig zu verwenden, oder wie kann man sicherstellen, dass das Problem im Live-Betrieb entweder abgefangen wird oder gar nicht mehr vorkommt?

Danke und Gruß,
Chris

Servus

Ich hab dir das Script im ersten Post dahingehend modifiziert das bei fehlenden Daten ein Defaultwert ausgegeben wird.
Mehr kann man net tun.

gruß
bb

Ah, ok, danke dir!!! Das reicht an sich, da kann man ja einfach einen unmöglich vorkommenden Wert nehmen und wenn dieser kommt, dann soll er es noch ein paar Mal probieren und erst wenn dann immer noch nicht klappt, dann einen Fehler ausgeben. Danke!!

Dachte auch eher, dass evtl. jemand von IPS sich das mal anschaut…falls ein Fehler im Archive-Handler vorliegt…

Grüße,
Chris

Ich verstehe das Skript noch nicht ganz und es funktioniert (vermutlich deshalb) bei mir auch nicht.

Ich habe einen Wert, der alle Sekunde aufläuft und den ich, auch zur Verrechnung mit anderen Werten, die in größeren Zeiträumen auflaufen (z.B. 30 Sekunden oder Minuten), gerne als Mittelwert auf die Zeitbasis der anderen Werte umrechnen möchte.

Die Werte laufen also auf eine Variable, die auch geloggt wird. Diese Variable hat eine ObjektID (39068).
Für die Mittelwerte habe ich eine zweite Variable angelegt, die auch geloggt wird und natürlich auch eine ObjektID (26885)hat.

Diese beiden ObjektIDs habe ich nun in die Zuweisung eingesetzt:

$IDArchiveHandler = 39068 /*your Archive Handler ID*/;
$varId = 26885 /*Var Id you want to examine*/;

Nun bekomme bei Ausführung des Skriptes die Fehlermeldung:

[i]Warning: AC_GetLoggedValues: Instance #39068 not found! in E:\IP-Symcon\scripts\43034.ips.php on line 14
Mean: 0

Warning: AC_GetLoggedValues: Instance #39068 not found! in E:\IP-Symcon\scripts\43034.ips.php on line 24
Median: 0[/i]

Auch wenn ich die Variablen umkehre, bekomme ich die Fehlermeldung, das die "IDArchiveHandler " nicht vorhanden sei.

Muss ich das Skript dann eigentlich mit einem Zeit-Ereignis ausführen?

Dank und Gruß
tango

Hi!

Falsch :smiley:

ArchiveHandler findest du in der IPS-Console unter „Kern Instanzen“. Dort gibt es dann das „Archiv“, davon die ID eintragen.
Und als 2. (varId) dann die ID von deiner Variable eintragen, aus der die Archivdaten gelesen werden sollen. Also von der Variable die gelogged wurde/wird.

Eine Ausgabe in eine andere Variable muss extra erfolgen!

Hier gibt es noch weitere Beispiele:
IP-Symcon - Wie kann ich… 2.0 - Seite 5

Grüße,
Chris