Ankündigung

Einklappen
Keine Ankündigung bisher.

Interpolation von Wetterdaten

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Interpolation von Wetterdaten

    Hallo Forum,

    ich habe eine Liste von Wetterdaten einer Wetterstation, die zwar zeitlich sortiert aufgenommen sind, aber in unterschiedlichsten Intervallen.
    z.B.:
    24.12.2014 00:05 0°C
    24.12.2014 00:12 0°C
    24.12.2014 01:34 -0.5°C
    24.12.2014 01:55 -0.5°C
    24.12.2014 03:55 -1°C
    usw.

    Tendenziell habe ich bereits einen Lösungsansatz(reine Mathematik) um für jeden vollen Stundenwert die Temperatur zu erhalten und so für den Tag 24 Werte zu erhalten.
    Bevor ich das ganze implementiere, wollte ich lediglich Fragen ob es bereits Bibliotheken gibt, die sich mit einer ähnlichen Problematik beschäftigen.
    Sollte das nicht der Fall sein, werde ich euch vermutlich im Nachhinein um Optimierungsratschläge bitten.
    mit freundlichen Grüßen und einen guten Rutsch wünschend
    Balli


  • #2
    Ob es Bibliotheken dafür gibt, kann ich dir nicht sagen. Über den Daumen geschätzt ist die Temperatur eine Funktion zweiten Grades (also y = ax^2 + bx + c). Wenn du da eine Regression (Quadratische Regression) machst solltest du die Temperatur ziemlich präzise interpolieren können.
    GitHub.com - ChrisAndChris - RowMapper und QueryBuilder für MySQL-Datenbanken

    Kommentar


    • #3
      über die Geschwindigkeit würde ich mir wenig Gedanken machen, es gibt eigentlich keine Interpolationsverfahren, die zu langsam wären (außer vielleicht die Klassische Polynominterpolation )
      Fatal Error: Windows wird gestartet

      Wie administriert man ein Netzwerk: Beispiel

      Kommentar


      • #4
        Zitat von ChristianK Beitrag anzeigen
        Über den Daumen geschätzt ist die Temperatur eine Funktion zweiten Grades (also y = ax^2 + bx + c). Wenn du da eine Regression (Quadratische Regression) machst solltest du die Temperatur ziemlich präzise interpolieren können.
        Wie kommst du auf diese Annahme?

        ballibum: Wo kommen die Daten her? Ich kenne es so, das Wetterstationen equidistante Werte liefern.
        PHP-Klassen auf github

        Kommentar


        • #5
          naja man kann fast alles recht gut intervallweise durch parabeln modellieren, auch wenn ich kubische Funktionen bevorzugen würde, da diese sich 2 mal ableiten lassen

          So zum Beispiel:

          http://www.arndt-bruenner.de/mathe/s.../kubspline.htm

          Algorithmen für das Gaußverfahren sind effizient und bestimmt auch schon in php implementiert, einfach mal nach suchen
          Fatal Error: Windows wird gestartet

          Wie administriert man ein Netzwerk: Beispiel

          Kommentar


          • #6
            Zitat von jspit Beitrag anzeigen
            Wie kommst du auf diese Annahme?

            ballibum: Wo kommen die Daten her? Ich kenne es so, das Wetterstationen equidistante Werte liefern.
            Dadurch, dass die quadratische Parabel einen Wendepunkt (Tagestiefsttemperatur/-höchsttemperatur) hat. Vielleicht (vermutlich) eignen sich andere Modelle besser - ich bin kein Meteorloge.
            GitHub.com - ChrisAndChris - RowMapper und QueryBuilder für MySQL-Datenbanken

            Kommentar


            • #7
              die quadratische Parabel hat keinen Wendepunkt, nur einen einzigen Hoch oder Tiefpunkt
              Fatal Error: Windows wird gestartet

              Wie administriert man ein Netzwerk: Beispiel

              Kommentar


              • #8
                Hi,
                vielen Dank für eure Antworten. Die Daten stammen leider aus einem "pseudo" Open Source Projekt (openweathermap) und da gibt es eben nicht zu jede vollen Stunde die Daten. Ist eben anders als bei Daten vom DWD.
                mfg
                Balli

                Kommentar


                • #9
                  Da reale Messwerte fehlerbehaftet sind und für Temperaturverläufe kein Gesetz existiert welches man in eine Formel pressen könnte, tendiere ich zu einer möglichst einfachen Lösung, in der zwischen jeweils zwei Punkten eine Geradengleichung angesetzt wird (Lineare Mehrpunkt-Interpolation).

                  Wie sieht denn nun dein Ansatz aus?

                  Am Rande: Warum soll OpenWeatherMap ein
                  "pseudo" Open Source Projekt
                  sein?
                  PHP-Klassen auf github

                  Kommentar


                  • #10
                    Hi,
                    ich tendiere auch zur linearen Interpolation und setze diese gerade um(dauert aber sich noch ein kleines bisschen, habe gerade nicht so viel zeit für Hobby-Geschichten), wenn der Code fertig ist werde ich Ihn hier posten und ihr könnte, dann bewerten an welchen Stellen es Verbesserungen gibt.

                    OpenWeatherMap habe ich mit pseudo bezeichnet, weil nicht alle Funktionen "for free" sind und auch nicht alle Parameter die "for free" sind hinhauen. Insgesamt aber ein ziemlich cooles Projekt in welches auch ich meine Wetterdaten demnächst zufüge. Meine Wortwohl '"pseudo" Open Source...' hätte nur Projekt heisen müssen, dann wäre es richtig.

                    mit bestem Gruß
                    Balli

                    Kommentar


                    • #11
                      Zitat von ballibum Beitrag anzeigen
                      Hi,
                      ich tendiere auch zur linearen Interpolation
                      Welche PG-Version hast Du? 9.4 bringt einige neue Funktionen mit, vielleicht helfen diese.

                      http://michael.otacoo.com/postgresql...-within-group/

                      Ich bin aber jetzt schon 'ne Weile aus Studium raus und weiß nicht, ob das hilfreich in Deinem Falle ist...
                      PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

                      Kommentar


                      • #12
                        Hi,
                        ja das ist sicherlich sehr interessant, das werde ich mir auch mal anschauen. Nur, damit ihr auch seht der Balli greift nicht nur ab, hier meine erste Version meines Interpolationscodes- ist noch ziemlich Quick und Dirty und es fehlt auch noch das ein oder andere (vor allem Prüfungen ob Werte gesetzt sind), aber es tut:

                        PHP-Code:
                        <?php

                        class openweather_weather
                        {
                            var 
                        $weatherofweatherstation = [];
                            var 
                        $interpolierteswetter NULL;
                            var 
                        $from NULL;
                            var 
                        $to NULL;
                            var 
                        $weatherstation NULL;

                            function 
                        openweather_weather($weatherstation$from$to)
                            {
                            
                        $this->weatherstation $weatherstation;
                            
                        $this->from $from;
                            
                        $this->to $to;
                            
                        $this->getweatherdatafromdatabase();
                                
                        $this->interpoliereweatherdata();
                            }

                            function 
                        getweatherdatafromdatabase()
                            {
                            
                        //select * from ow_example_2844588 where timestamp>'2014-12-20' and timestamp <'2014-12-28';
                            
                        $result db_query("SELECT * from ".$this->weatherstation." where timestamp >'".$this->from."' and timestamp < '".$this->to."';" );
                            foreach (
                        $result as $entry)
                            {
                                
                        //Temperatur umwandeln in °C durch die Subtraktion von -273.5
                                    
                        $values = new weatherentry($entry->timestamp$entry->rain$entry->temp-273.5$entry->snow$entry->humidity);
                                    
                        array_push($this->weatherofweatherstation,$values);
                            }
                            }
                            
                            function 
                        interpoliereweatherdata()
                            {
                                
                        //$this->weatherofweatherstation;
                                
                        $datum = [];
                                
                        $datumundzeit = [];
                                foreach (
                        $this->weatherofweatherstation as $wetter)
                                {
                                    
                        array_push($datumsubstr($wetter->timestamp010));
                                }
                                
                        //die Stunden einfügen die ich möchte von 00:00 Uhr bis 23:00 Uhr
                                
                        foreach (array_unique($datum) as $day)
                                {
                                    
                        $i 0;
                                    while (
                        $i<24)
                                    { 
                                        if(
                        $i<10)
                                        {
                                            
                        array_push($datumundzeit,$day.' 0'.$i.':00:00+01');
                                        }
                                        else
                                        {
                                            
                        array_push($datumundzeit,$day.' '.$i.':00:00+01');
                                        }
                                        
                        $i++;
                                    }
                                }
                                
                        //für jede Zeit Vor- und Nachfolger finden
                                
                        foreach($datumundzeit as $datetime)
                                {
                                    
                        $options['difference_min_null'] = NULL;
                                    
                        $options['temp_min'] = NULL;
                                    
                        $options['rain_min'] = NULL;
                                    
                        $options['snow_min'] = NULL;
                                    
                        $options['humidity_min'] = NULL;
                                    
                        $options['difference_max_null'] = NULL;
                                    
                        $options['temp_max'] = NULL;
                                    
                        $options['rain_max'] = NULL;
                                    
                        $options['snow_max'] = NULL;
                                    
                        $options['humidity_max'] = NULL;
                                    
                        $options['kleiner'] = NULL;
                                    
                        $options['groesser'] = NULL;
                                    foreach (
                        $this->weatherofweatherstation as $wetter)
                                    {  
                                       
                        $difference strtotime($datetime) - strtotime($wetter->timestamp);
                                       if (
                        $difference 0)
                                       {
                                           if(
                        $difference $options['difference_min_null'] || is_null($options['difference_min_null']))  //Überprüfen ob der Abstand kleiner als der Vorhandene ist
                                           
                        {
                                               
                        $options['kleiner'] = $wetter->timestamp;
                                               
                        $options['difference_min_null'] = $difference;
                                               
                        $options['temp_min'] = $wetter->temp;
                                               
                        $options['rain_min'] = $wetter->rain;
                                               
                        $options['snow_min'] = $wetter->snow;
                                               
                        $options['humidity_min'] = $wetter->humidity;
                                           }
                                       }
                                       else
                                       {
                                           if(
                        $difference $options['difference_max_null'] || is_null($options['difference_max_null']))  //Überprüfen ob der Abstand kleiner als der Vorhandene ist
                                           
                        {
                                               
                        $options['groesser'] = $wetter->timestamp;
                                               
                        $options['difference_max_null'] = $difference;
                                               
                        $options['temp_max'] = $wetter->temp;
                                               
                        $options['rain_max'] = $wetter->rain;
                                               
                        $options['snow_max'] = $wetter->snow;
                                               
                        $options['humidity_max'] = $wetter->humidity;
                                           }
                                       }     
                                    }
                                    
                        $this->openweatherinterpol($datetime,$options);
                                }
                            }
                            
                            function 
                        openweatherinterpol($datetime,$options)
                            {
                                
                        $inttemp NULL;
                                
                        $intrain NULL;
                                
                        $intsnow NULL;
                                
                        $inthumidity NULL;
                                if(
                        is_null($options['groesser']) && !is_null($options['kleiner']))
                                {
                                    
                        $inttemp $options['temp_min'];
                                    
                        $intrain $options['rain_min'];
                                    
                        $intsnow $options['snow_min'];
                                    
                        $inthumidity $options['humidity_min']; 
                                }
                                elseif(!
                        is_null($options['groesser']) && is_null($options['kleiner']))
                                {
                                    
                        $inttemp $options['temp_max'];
                                    
                        $intrain $options['rain_max'];
                                    
                        $intsnow $options['snow_max'];
                                    
                        $inthumidity $options['humidity_max']; 
                                }
                                else
                                {
                                    
                        $inttemp interpolierung($options['difference_min_null'],$options['difference_max_null'],$options['temp_min'],$options['temp_max']);
                                    
                        $intrain interpolierung($options['difference_min_null'],$options['difference_max_null'],$options['rain_min'],$options['rain_max']);
                                    
                        $intsnow interpolierung($options['difference_min_null'],$options['difference_max_null'],$options['rain_min'],$options['snow_max']);
                                    
                        $inthumidity interpolierung($options['difference_min_null'],$options['difference_max_null'],$options['rain_min'],$options['humidity_max']);
                                }
                                
                        $interpoliertesWetter = new interpolweatherentry($datetime$intrain$inttemp$intsnow$inthumidity);
                                
                        array_push($this->interpolierteswetter,$interpoliertesWetter);
                            }
                            function 
                        interpolierung($diffmin,$diffmax,$valuemin,$valuemax)
                            {
                                if(
                        $diffmin<0)
                                {
                                    
                        $diffmin $diffmin * -1;
                                }
                                if(
                        $diffmax<0)
                                {
                                    
                        $diffmax $diffmax * -1;
                                }
                                
                        $diff $diffmin $diffmax;
                                
                        $valuediff $valuemax $valuemin;
                                
                        $intervall $valuediff $diff;
                                
                        $value $valuemin + ($diffmin*$intervall);
                                return 
                        $value;
                            }
                        }

                        class 
                        weatherentry
                        {
                            var 
                        $timestamp null;
                            var 
                        $temp null;
                            var 
                        $rain null;
                            var 
                        $snow null;
                            var 
                        $humidity null;
                            
                            function 
                        weatherentry($timestamp,$rain,$temp,$snow,$humidity)
                            {
                                
                        $this->timestamp =$timestamp;
                                
                        $this->temp $temp;
                                
                        $this->snow $snow;
                                
                        $this->rain $rain;
                                
                        $this->humidity $humidity;
                            } 
                        }

                        class 
                        interpolweatherentry
                        {
                            var 
                        $timestamp null;
                            var 
                        $temp null;
                            var 
                        $rain null;
                            var 
                        $snow null;
                            var 
                        $humidity null;
                            
                            function 
                        interpolweatherentry($timestamp,$rain,$temp,$snow,$humidity)
                            {
                                
                        $this->timestamp =$timestamp;
                                
                        $this->temp $temp;
                                
                        $this->snow $snow;
                                
                        $this->rain $rain;
                                
                        $this->humidity $humidity;
                            } 
                        }
                        mit bestem Gruß und einen schönen Restsonntag
                        Balli

                        Kommentar


                        • #13
                          Dein Klassenkonstrukt besitzt für meinen Geschmack zu viele Abhängigkeiten (Datenbank, Wetter-API..).
                          Hab mir mal Gedanken gemacht, wie eine Klasse für lineare Mehrpunktinterpolation möglichst einfach und dennoch universell genutzt werden kann.

                          Hier mein Entwurf:

                          Als Datenbasis dient ein mehrdimensionales Array, wie es typischer Weise mit fetchAll bei einer Datenbankabfrage geliefert wird.

                          Beispiel:
                          PHP-Code:
                          $data = array(
                            array(
                          'time' => '2000-1-1 00:00','temp' => -1,'temp2' => -1),
                            
                          // :
                            
                          array('time' => '2000-1-2 00:00','temp' => -4,'temp2' => 0),
                            ); 
                          Die x-Werte sind hier Datumsstrings und so nicht für eine Interpolation nutzbar. Damit unsere Klasse universell nutzbar bleibt, werden bei der Instanzerstellung noch die Schlüssel für x und y sowie eine Funktion zur Transformation der Datumsstrings in einen Timestamp mitgegeben:
                          PHP-Code:
                          $transX = function($d){
                            if(
                          is_string($d)) $d date_create($d);
                            return 
                          $d->getTimeStamp(); 
                          };

                          $lip = new LinIntPol($data ,'time','temp'$transX); 
                          Die Klasse kennt in der ersten Ausbausufe nur die eine Methode getValue(),
                          welche einen interpolierten Wert liefert:
                          PHP-Code:
                          $temp $lip->getValue('2000-1-1 18:00'); 
                          Eine solche Klasse besitzt eine überschaubare Aufgabe und ist flexibel nutzbar.

                          LG jspit
                          PHP-Klassen auf github

                          Kommentar

                          Lädt...
                          X