Gleitenden Mittelwert oder gleitenden Median berechnen

Guten Morgen,

ich bin gerade mit dem Skript am herum probieren um die Leistungsaufnahme meiner Geräte im Waschkeller zu mitteln und daraus den Aktiv-Status zu berechnen.
Mir ist im Augenblick nicht ganz klar was der unterschied zwischen dem „Mean-“ und „Median-Wert“ ist.
Könnt Ihr mir das bitte kurz erlkären?

Danke und LG Michi

Guten Morgen,
ich habe das script auch probiert und es liefert andere Werte als

	$werte = AC_GetAggregatedValues(31304 /*[Archive Handler]*/, 58259 , 0 , (time()-(60*60*24)),(time()), 0);
	foreach($werte as $wert) {
	$durchschnittHeute=	 $wert['Avg'] ;

Das script liefert anscheinend den richtigen Wert.

Mir ist im Augenblick nicht ganz klar was der unterschied zwischen dem „Mean-“ und „Median-Wert“ ist.
Könnt Ihr mir das bitte kurz erlkären?

Würde mich auch interessieren…:o
Wie könnte man denn den Mittelwert für den gestrigen Tag ermitteln?
Grüße Jens

Servus
Mathematische Hintergründe kannst im Wiki nachlesen.

Nur so viel:

  • der Mean (arithmetischer Mittelwert) ist die klassische Mittelwertberechnung wie wir das alle in der Schule gelernt haben.
  • der Median (geometrischer Mittelwert) ist ähnlich, allerdings wesentlich robuster gegen Ausreißer.

Bsp: Du hast 5 Messwerte mit 18,20,22,20,500. Der 500er Wert ist aber ein Fehler welcher bsp. durch einen Wackelkontakt passiert ist.
Dieser Ausreißer würde den Mean/Mittelwert komplett verfälschen und du bekämst 112 raus.
berechnet man aber über die Medianmethode so kriegst du 22 raus.

In diesem Fall ist der 500 klar als Fehlmessung erkennbar und man könnte diesen Wert auch auch anders wegfiltern.
In vielen Fällen geht das aber nicht so einfach und dann kommt die Medianmethode zum Einsatz. Der Nachteil ist eine etwas aufwändigere Berechnung.

gruß
bb

Moin Michi!

Nimm den „Median“ über die letzten 2-3 Minuten deiner geloggten Stromverbrauchswerte, dann werden die Trommeldrehungen nach Waschende „gefiltert“ und du bekommst deine Waschmaschinenmeldungen :wink:

Grüße,
Chris

Hallo bbernhard, hallo Chris,

danke für Eure Erklärungen und Eure Tipps. :slight_smile:

Komischerweise habe ich beim beobachten der beiden Werten genau das Gegenteil festgestellt.
Der Mean ist bei mir um einiges stabiler, als der Median. grübel :confused:
Ich spiele jetzt einfach noch mal mit den Werten herum. Mal sehen welcher der Beiden für meine Berechnung besser in Frage kommt.

Hallo Leute,

ich habe das script an meinem 1-wire Außentemperatursensor getestet. In diesem Fall ist der Meanwert der Richtige, Ausreißer kann man hier bei der Abfrage filtern, denn die Außentemperatur steigt z.B. nie in 10 min um 10°.
In Wikipedia ist das übrigens gut beschrieben. Danke für die Allgemeinbildung.:smiley:
Kann man das für den gestrigen Tag so

function getMean ($IDArchivehandler,$varId,$log_interval,$default) {
$logData = AC_GetLoggedValues ($IDArchivehandler, $varId, time()- $log_interval,(time()-(24*60*60)),-1);
if (count($logData) <1) return $default;

machen?
Grüße Jens

Hallo zusammen.

Da ich noch ein Neuling in der Skript Programmierung bin, benötige ich eure Hife. :confused:

Wie bekomme ich die berechneten Werte vom Skript „Mean oder Median“ in eine Variable?
Ich habe es mit SetValue versucht, aber bin gescheitert.

Besten Dank
Michael

Um was für eine Variable handelt es sich denn, eine eigene selbst erstellte?
Kannst Du mal den Code posten, mit dem Du versuchst den Median zu beschreiben?

Hallo zusammen.

Ich würde gern die ausgegebenen Werte des Skripts in je eine selbst erstellte Variable schreiben.
Ich habe es mit SetValue versucht, aber bin gescheitert.

Besten Dank,
Michael

 <?
$IDArchiveHandler = 27158 /*your Archive Handler ID*/;
$varId = 34047 /*Var Id you want to examine*/;
$interval = 300; /*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];
}

?> 

du hast es mit SetValue versucht ? wie denn ? in deinem geposteten Code steht nichts von SetValue … ? Du bist gescheitert? woran denn, was kam als Fehlermeldung ?

Das ist hier sehr genau beschrieben: SetValue — IP-Symcon :: Automatisierungssoftware
Ohne, dass du mal zeigst was du gemacht hast, bleibt nur der Verweis auf die Doku, besser als dort könnte ich es auch nicht beschreiben.

Hi,
ist zwar ein alter Post trotzdem wollte ich eine Korrektur vorbringen.

Median sollte besser 20 liefern:-) Median nimmt nicht einfach nur den Wert in der Mitte sondern den Wert in der Mitte nachdem sortiert worden ist und das macht die Sache so schwierig.

Ralf

Für einen Menschen macht es das sortieren bei großen Datenmengen durchaus schwierig, aber dafür hat man ja einen Computer, dem ist es egal ab er 5 Zahlen sortieren soll oder 50000 Zahlen ;).


echo "Median: ".getMedian ([18,20,22,20,500]); 
function getMedian ($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];
		}
} 

Hi Fonzo,
kommt auf die Datenmenge an die man filtern will. Ein großer Median über viele Daten kann ein Regelsystem schon stören. 5er oder 7er Median um grobe Ausreißer zu entfernen ist kein Problem.

Ralf

Hi,

auch hier noch eine kleine Ergänzung von mir. Mean ist praktisch ein Filter der „entrauscht“, die Kurven werden schön glatt gemacht und sehen einfach schön aus. Median entfernt nur Ausreißer und rauschige Kurven bleiben rauschig und sehen nicht so schön aus. Mathematisch ist das Median-Ergebnis meist ehrlicher als Mean.

Ralf

Besten Dank, habe es nun selber hinbekommen.

 <?
$IDArchiveHandler = 27158 /*your Archive Handler ID*/;
$varId = 34047 /*Var Id you want to examine*/;
$interval = 300; /*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'];
    SetValueFloat(15975, array_sum($value)/count($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'];
    SetValueFloat(20593, $value[count($value)/2]);
}
asort($value);
return $value[count($value)/2];
}

?> 

Du sprichst in Deinem Skript den Key des Array an, indem Du fest durch 2 teilst. Das kann funktionieren, wenn die Anzahl des Arrays eben durch 2 teilbar ist. Es kann aber auch schief gehen wenn die Anzahl der Elemente sich nicht durch 2 teilen lässt. Eventuell solltest Du das berücksichtigen s.o… Wenn Du z.B einen Array aus 3 Werten hast, dann wäre 3/2 = 1,5. Es gibt aber keinen Key mit dem Schlüssel 1,5, der mittlere Schlüssel von 0,1, 2 ist 1.

Hallo Fonzo.

Da ich noch sehr unerfahren bei der Skript Programmierung und kein Mathematiker bin, habe ich das von bbernhard eingestellte Skript verwendet und so modifiziert, dass ich die Werte in je eine Variable bekomme.
Ich benötige den Mittelwert zur um Windspitzen für eine Jalousien- Steuerung auszufiltern.
Ich habe das Ganze auch schon mit diesem Skript versucht, aber die Spitzenwerte werden damit nicht ausgefiltert.

<?

$start = time() - 300;  // vor 5 Minuten
$ende  = time();  // jetzt  

$werte = AC_GetAggregatedValues(27158, 34047, 5, $start, $ende, 0); 
  
foreach($werte as $wert)  
     { 
     SetValueFloat(49372, $wert['Avg']); 
    } 
   

?>

Was kann ich ändern, damit die Daten vom Skript fehlerfrei sind?
Für Hilfe wäre ich dankbar.

Das passt schon alles soweit, in Deinem Skript nutzt Du ja die Funktion getMean, das gibt Dir den Mittelwert aus. Meine Anmerkung bezog sich nur auf den Median, also die Funktion getMedian.

Ohh der uralte post kommt wieder ans Tageslicht :slight_smile:
Ehrlich gesagt ich habe jetzt nicht mehr alles gelesen, aber bei einer Jalousie Steuerung möchte ich doch gearde die Spitzenwerte haben um rechtzeitig einzfuhren.
Denn die Windböen machen mir doch meine Jalousie kaputt. Diese wegzubüglen wäre wohl genau das Gegenteil von dem was man erreichen will.
Oder hält die Jalousie jeden Sturm aus und du möchtest sie aus thermischen Gründen ab einer gewischen Windstärke ausgefahren haben?

greez
bb

Ich habe bei dem Skript ein Problem.

Ich habe einen Lichtsensor (Integer Wert 0-1000)

der wird jede Minute ausgelesen. Solange sich die Werte ändern läuft es auch super.
Aber sobald er zur Mittagssonne nur noch 1000 anzeigt wird mir als Median und Mean nur noch 0 ausgegeben.

Kann mir da jemand helfen ?