Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]Obliczanie średniej z danych pobranych z pliku TXT
Forum PHP.pl > Forum > Przedszkole
nacek
Witam
Proszę o pomoc na forum bo choć z wielu wątków już skorzystałem to nadal jestem w przedszkolu.
Problem wygląda następująco.
Mam surowe dane meteorologiczne w pliku tekstowym. Wyniki zapisane są co 10 minut a cały plik zawiera dane z miesiąca.
Chcę obliczyć średnie dobowe.
Znalazłem następujące przykłady:
1. Wyciągnięcie danych z wybranego dnia
  1. $plik = "../Statystyki/miesiąc_dane.txt";
  2. $dane = file($plik); /* pobieram dane z pliku i zapisuje do tablicy (linia = rekord) */
  3.  
  4. for($i=0;$i<count($dane);$i++) { /* przeszukuję tablicę */
  5. list($data[$i], $godzina[$i], $temperatura[$i], $pozostałe...[$i] ) = explode("|", $dane[$i]);
  6. /* dziele linię na tablicę i zapisuje dane do odpowiednich zmienncyh */
  7.  
  8. }
  9.  
  10. for($i=0;$i<count($data);$i++) /* przeszukuję tablicę */
  11. if($Wybrany_dzien == $data[$i]){
  12.  
  13. $Temp .=$temperatura[$i].', '; /* wybieram dane i przypisuję do zmiennej */
  14. }

echo $Temp wyświetla ciąg liczb oddzielonych przecinkami - więc chyba OK.
2. Liczenie średniej
  1. function srednia()
  2. {
  3. $liczby = func_get_args();
  4. return array_sum($liczby)/func_num_args();
  5. }

I jak teraz zapisać średnią do zmiennej?
Gdy wpisuję
  1. $SredniaTemp = srednia($Temp);
Dostaję tylko pierwszą liczbę a nie średnią z wybranych.
Funkcja "srednia" działa gdy wstawiam ciąg liczb więc nie wiem dlaczego wstawienie zmiennej nie daje tego samego wyniku.
marcinM97
Cześć.

Poniżej zamieszczam skrypt o bliźniaczej funkcjonalności.
Nie ma pliku wsadowego, ale jest losowe generowanie temperatur na dane dni.
Na razie załączam, mam nadzieję, że Ci się przyda.
Jeśli znajdę czas, przeanalizuję twój kod i wskażę, co trzeba poprawić.

  1. //Symulacja danych wejściowych:
  2. $dane_wejsciowe = array();
  3. $data = 0;
  4. $godzina = 1;
  5. $doba_ilosc_godzin = 24;
  6. $miesiac_ilosc_dni = 30;
  7. $interwal = 10; //Zbieramy dane co określony interwał, np. co 10 minut.
  8. for($a = 0; $a <= ($interwal*$doba_ilosc_godzin*$miesiac_ilosc_dni-1); $a++) { //Pętla tworzy dane wejściowe. Temperatura dobierana jest losowo.
  9. if($a % ($interwal*$doba_ilosc_godzin) == 0) { //Zmiana daty na kolejną
  10. $data ++;
  11. $godzina = 0;
  12. }
  13. $godzina ++;
  14. $temperatura = rand(0,30);
  15. $inne = '';
  16. $dane_wejsciowe[] = array('data' => $data, 'godzina' => $godzina, 'temperatura' => $temperatura, 'inne' => $inne);
  17. }
  18.  
  19. //Obliczamy średnie temperatury dobowe:
  20. $temp_suma = 0;
  21. $temperatury_dobowe = array();
  22. $data_biezaca = 0;
  23. foreach($dane_wejsciowe as $dane) {
  24. $temp_suma += $dane['temperatura'];
  25. if($data_biezaca != $dane['data']) { //Jeśli zmienia się data, zapisujemy do tablicy średnią temeraturę z danego dnia.
  26. $temperatury_dobowe[$dane['data']] = $temp_suma/($doba_ilosc_godzin*$interwal);
  27. $temp_suma = 0;
  28. }
  29. $data_biezaca = $dane['data'];
  30. }
  31.  
  32. var_dump($temperatury_dobowe);
  33.  
  34. //Obliczamy średnią temeperturę dobową, jako średnia ze średnich z każdego dnia.
  35. $ilosc_dni = count($temperatury_dobowe);
  36. var_dump('ilosc dni: '.$ilosc_dni);
  37. $suma = array_sum($temperatury_dobowe);
  38. var_dump('suma: '.$suma);
  39. $wynik = $suma/$ilosc_dni;
  40. var_dump('wynik: '.$wynik);


"
Dostaję tylko pierwszą liczbę a nie średnią z wybranych.
Funkcja "srednia" działa gdy wstawiam ciąg liczb więc nie wiem dlaczego wstawienie zmiennej nie daje tego samego wyniku.

"

finct_get_args() zwraca tablicę.
Z tego co opisujesz wkłądasz do funkcji srednia() stringa. Dla tego może nie działać.
Przerób go najpierw:
$Temp = explode(',', $Temp);
tzm
  1. function srednia($liczby)
  2. {
  3. return array_sum($liczby)/count($liczby);
  4. }


z palca a bledu nie szukalem bo nie ma pliku wsadowego... dalbys przyklad.
nacek
Cytat(marcinM97)
Poniżej zamieszczam skrypt o bliźniaczej funkcjonalności.

To za skomplikowane.

Cytat(marcinM97)
finct_get_args() zwraca tablicę.
Z tego co opisujesz wkłądasz do funkcji srednia() stringa. Dla tego może nie działać.
Przerób go najpierw:
$Temp = explode(',', $Temp);

Poszedłem tym tropem chociaż zapisałem inaczej:
  1. $Temp[] .=$temperatura[$i].''; /* wybieram dane i przypisuję do zmiennej */

Funkcja średniej (ta w pierwszym poście) zwracała w tym wypadku "0".
Więc sprawdzałem dalej.
Cytat(tzm)
  1. function srednia($liczby)
  2. {
  3. return array_sum($liczby)/count($liczby);
  4. }


z palca a bledu nie szukalem bo nie ma pliku wsadowego... dalbys przyklad.

Tak zapisana funkcja wyrzuca błędy: "array_sum() expects parameter 1 to be array",
ALE! -oblicza średnią prawidłowo.
Więc na razie zrezygnowałem z funkcji i zapisałem po prostu działanie:
  1. $SredniaTemp = round(array_sum($Temp)/count($Temp), 1);
(z zaokrągleniem do 1 miejsca).

Może jeszcze ktoś zaproponuje funkcję do liczenia średniej, która sprawdzała by się w takiej sytuacji?

Mam jeszcze jedną wątpliwość przy liczeniu średniej dla wartości np. promieniowania słonecznego. Nie ma przecież sensu obliczać dla całej doby. Tylko jak wyciągnąć dane z pliku tylko dla części doby?
Przykładowo: plik z danymi za sierpień 2014
W kolumnach kolejno: data | godzina | temperatura | temp.max | temp.min | punkt rosy | wilgotność | intensywność opadu | intensywnosc.max | suma opadu z 10min | suma dzienna narastająco | ciśnienie | wiatr sredni | podmuch | kirunek wiatru litery ang. | kierunek stopnie | index uv | indexuv.max | promieniowanie slonca | promieniowanie.max. (wartości podstawowe to średnie z ostatnich 10 minut a max/min to skrajne zarejestrowane w tym czasie)
W moim kodzie trzeba podstawić $Wybrany_dzien = '1-08-2014'; lub następne wink.gif
tzm
No to znaczy że nie przekazywałeś tablicy jako parametru funkcji. Potem zerknę bo w pracy już jestem a to dłuższy temat.
nacek
Cytat
Tylko jak wyciągnąć dane z pliku tylko dla części doby?

Sam siebie cytuję bo tak zadanie pytanie więcej komplikuje.
Powinienem zapytać: jak policzyć średnią tylko dla wartości dodatnich?
Rozwiązanie znalazłem tu choć z innym warunkiem:
Średnia arytmetyczna
Czyli warto czasem pokopać w starszych i bardziej ogólnie zatytuowanych tematach.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.