encorez Juniormester
08. november 2018 - 22:32 Der er 6 kommentarer

Average af datapunkter inden for en tidsramme

Hej

Jeg har et datasæt med bl.a. timestamp (dato - tid) og en værdi.

Jeg har brug for en funktion hvor jeg løber datasættet igennem og for hvert eneste punkt skal udregnes gennemsnitsværdien af datapunkter for de seneste 2 timer for eksempel. Tidsrammen skal være variabel.

Mine datapunkter kommer ikke nødvendigvis med samme interval, og derfor bliver det lidt kringlet.

Er der nogen der har godt forslag til at løse den opgave bedst mulig?

Og da jeg ikke er java-haj, så vil et kode-eksempel eller semi-kode være meget behjælpelig.

Tusind tak på forhånd
arne_v Ekspert
08. november 2018 - 23:20 #1
Til inspiration:


import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.function.BiConsumer;

public class DataAnalysis {
    public static class DataPoint {
        private Timestamp timestamp;
        private double value;
        public DataPoint(Timestamp timestamp, double value) {
            this.timestamp = timestamp;
            this.value = value;
        }
        public DataPoint(long epochtime, double value) {
            this(new Timestamp(epochtime), value);
        }
        public Timestamp getTimestamp() {
            return timestamp;
        }
        public double getValue() {
            return value;
        }
    }
    public static class DataSet {
        private List<DataPoint> datapoints = new ArrayList<>();
        public void add(DataPoint dp) {
            datapoints.add(dp);
        }
        public int size() {
            return datapoints.size();
        }
        public DataPoint get(int ix) {
            return datapoints.get(ix);
        }
    }
    public static class DataAnalyzer {
        private DataSet dataset;
        private int interval;
        public DataAnalyzer(DataSet dataset, int interval) {
            this.dataset = dataset;
            this.interval = interval;
        }
        public void process(BiConsumer<DataPoint, Double> f) {
            int ix0 = 0;
            for(int ix = 0; ix < dataset.size(); ix++) {
                while(dataset.get(ix0).getTimestamp().getTime() < dataset.get(ix).getTimestamp().getTime() - interval) ix0++;
                double avg = 0;
                for(int i = ix0; i <= ix; i++) {
                    avg += dataset.get(i).getValue();
                }
                avg /= (ix - ix0 + 1);
                f.accept(dataset.get(ix), avg);
            }
        }
       
    }
    public static void main(String[] args) {
        long now = (new Date()).getTime();
        DataSet ds = new DataSet();
        ds.add(new DataPoint(now - 5000, 1.0));
        ds.add(new DataPoint(now - 3000, 4.0));
        ds.add(new DataPoint(now - 2000, 9.0));
        ds.add(new DataPoint(now - 1000, 16.0));
        ds.add(new DataPoint(now -    0, 25.0));
        DataAnalyzer da = new DataAnalyzer(ds, 1500);
        da.process((dp,avg) -> System.out.println(dp.getValue() + " " + avg));
    }
}
encorez Juniormester
10. november 2018 - 18:55 #2
Hej

Tusind tak for det her eksempel :)

Jeg har siddet og kigget på det flere gange for at forstå hvad der sker visse steder for det er lidt komplekst et par steder :)

Jeg går ud fra at tidspunktet skal være et timestamp, så jeg skal konvertere min datetime (YYYY-MM-DD HH:MM:SS) til et timestamp ikke sandt?

Når du i eksemplet angiver "1500", så er det i sekunder ikke sandt?

Men der er en ekstra vigtig ting jeg glemte i første omgang, beklager. Mit datasæt går fra mandag kl 8.00 -> fredag kl 16.00, en arbejdsuge kan man sige.
Men når jeg regner mit gennemsnit ud, så skal weekend-tidsrummet ikke regnes med som "tid". Funktionen skal altså tro at mandag kl 8, kommer LIGE efter fredag kl 16.
F.eks. mandag kl 9, skal jeg bruge gennemsittet for de sidste 4 timers datapunkter, så skal den medtage datapunkter fra fredag 13 -> mandag kl 9; altså fredag 13-16 og mandag 8-9 = 4 timer i alt.

Jeg ved det er kringlet. Er det for komplekst at indbygge?
arne_v Ekspert
10. november 2018 - 19:03 #3
De 1000, 1500, 2000 etc. er millisekunder.

java.sql.DateTime er lige saa god som java.sql.Timestamp.
arne_v Ekspert
10. november 2018 - 19:03 #4
mandag fredag reglen er mere tricky, men alt kan jo kodes med lidt omhu.
arne_v Ekspert
15. november 2018 - 04:11 #5
Der er ikke nogen java.sql.DateTime - database DATETIME mappes til java.sql.Timestamp, saa den del er OK.
arne_v Ekspert
15. november 2018 - 04:16 #6
Det andet problem maa skulle loeses ved at aendre:

while(dataset.get(ix0).getTimestamp().getTime() < dataset.get(ix).getTimestamp().getTime() - interval) ix0++;

til:

while(dataset.get(ix0).getTimestamp().getTime() < dataset.get(ix).getTimestamp().getTime() - interval - extra(dataset.get(ix), interval)) ix0++;

hvor extra returnerer antal millisekunder der skal skippes.

0 normalt
64*60*60*1000 for weekend
63*60*60*1000 og 65*60*60*1000 for weekender hvor der aendres til/fra sommertid
Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links

Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester





Premium
Tre måneder forsinket: Den skandaleramte Windows 10-opdatering ‘1809’ ruller nu omsider automatisk ud
Den skandaleramte Windows 10-opdatering kaldet ‘1809’, som blev trukket tilbage få dage efter lanceringen 2. oktober 2018, begynder nu at rulle ud til brugerne helt automatisk via Windows Update.
CIO
Tech fra Toppen: Tim Vang får hastigheden op og de rigtige idéer frem med Googles pretotyping
Tech fra Toppen: Tim Vang får ideerne frem og hastigheden op ved konstant at tænke små overskuelige eksperimenter ind idéprocessen. Metoden hedder pretotyping og stammer fra Google. Lær meget mere om, hvordan du kan bruge værktøjet her.
Job & Karriere
Efter blodrødt regnskab: Nu fyrer Atea 20 medarbejdere i Danmark
Atea fyrer nu 20 medarbejdere. Det sker som en direkte konsekvens af, at den danske forretning er under pres, oplyser selskabets direktør.
White paper
Gratis e-bog: Mister du pusten på BI-bjergetapen? Tag den lige vej i stedet!
Denne e-bog er relevant for dig der sidder i en virksomhed, der allerede arbejder med Dynamics 365 for Finance & Operations, eller som overvejer at få det. Det er din genvej til at komme tilbage på BI-motorvejen, hurtigt og på den rigtige måde. Du finder ud af hvordan du kommer ud over bumpene og uden om hullerne på bjergvejen med CBI Plugin, så du igen kommer tilbage på motorvejen og kan køre direkte mod målet. Læs videre og bliv klogere på, hvordan du kommer over – eller helt undgår – de største bump på bjergetapen.