Freigeben über


time_weighted_avg2_fl()

Gilt für: ✅Microsoft Fabric✅Azure Data ExplorerAzure MonitorMicrosoft Sentinel

Die Funktion time_weighted_avg2_fl() ist eine benutzerdefinierte Funktion (UDF), die den zeitgewichteten Mittelwert einer Metrik in einem bestimmten Zeitfenster über Eingabezeitcontainer berechnet. Diese Funktion ähnelt dem Zusammenfassungsoperator. Die Funktion aggregiert die Metrik nach Zeitcontainern, aber anstatt einfache Durchschnittliche() des Metrikwerts in jedem Bin zu berechnen, wird jeder Wert nach seiner Dauer gewichtet. Die Dauer wird vom Zeitstempel des aktuellen Werts bis zum Zeitstempel des nächsten Werts definiert.

Es gibt zwei Optionen zum Berechnen des zeitgewichteten Mittelwerts. Diese Funktion interpoliert den Metrikwert linear zwischen aufeinander folgenden Beispielen. Alternativ time_weighted_avg_fl() füllt den Wert aus dem aktuellen Beispiel bis zum nächsten aus.

Syntax

T | invoke time_weighted_avg2_fl(, t_col y_col, key_col, stime etime dt, , )

Erfahren Sie mehr über Syntaxkonventionen.

Parameter

Name Type Erforderlich Beschreibung
t_col string ✔️ Der Name der Spalte, die den Zeitstempel der Datensätze enthält.
y_col string ✔️ Der Name der Spalte, die den Metrikwert der Datensätze enthält.
key_col string ✔️ Der Name der Spalte, die den Partitionsschlüssel der Datensätze enthält.
stime datetime ✔️ Die Startzeit des Aggregationsfensters.
etime datetime ✔️ Die Endzeit des Aggregationsfensters.
dt timespan ✔️ Der Aggregationszeitcontainer.

Funktionsdefinition

Sie können die Funktion definieren, indem Sie den Code entweder als abfragedefinierte Funktion einbetten oder wie folgt als gespeicherte Funktion in Ihrer Datenbank erstellen:

Definieren Sie die Funktion mithilfe der folgenden Let-Anweisung. Es sind keine Berechtigungen erforderlich.

Wichtig

Eine Let-Anweisung kann nicht alleine ausgeführt werden. Auf sie muss eine tabellarische Ausdrucksanweisung folgen. Informationen zum Ausführen eines funktionierenden Beispiels time_weighted_avg_fl()finden Sie unter Beispiel.

let time_weighted_avg2_fl=(tbl:(*), t_col:string, y_col:string, key_col:string, stime:datetime, etime:datetime, dt:timespan)
{
    let tbl_ex = tbl | extend _ts = column_ifexists(t_col, datetime(null)), _val = column_ifexists(y_col, 0.0), _key = column_ifexists(key_col, '');
    let _etime = etime + dt;
    let gridTimes = range _ts from stime to _etime step dt | extend _val=real(null), dummy=1;
    let keys = materialize(tbl_ex | summarize by _key | extend dummy=1);
    gridTimes
    | join kind=fullouter keys on dummy
    | project-away dummy, dummy1
    | union tbl_ex
    | where _ts between (stime.._etime)
    | partition hint.strategy=native by _key (
      order by _ts desc, _val nulls last
    | scan declare(val1:real=0.0, t1:datetime) with (                // fill backward null values
        step s: true => val1=iff(isnull(_val), s.val1, _val), t1=iff(isnull(_val), s.t1, _ts);)
    | extend dt1=(t1-_ts)/1m
    | order by _ts asc, _val nulls last
    | scan declare(val0:real=0.0, t0:datetime) with (                // fill forward null values
        step s: true => val0=iff(isnull(_val), s.val0, _val), t0=iff(isnull(_val), s.t0, _ts);)
    | extend dt0=(_ts-t0)/1m
    | extend _twa_val=iff(dt0+dt1 == 0, _val, ((val0*dt1)+(val1*dt0))/(dt0+dt1))
    | scan with (                                                    // fill forward null twa values
        step s: true => _twa_val=iff(isnull(_twa_val), s._twa_val, _twa_val);)
    | extend diff_t=(next(_ts)-_ts)/1m
    )
    | where isnotnull(diff_t)
    | order by _key asc, _ts asc
    | extend next_twa_val=iff(_key == next(_key), next(_twa_val), _twa_val)
    | summarize tw_sum=sum((_twa_val+next_twa_val)*diff_t/2.0), t_sum =sum(diff_t) by bin_at(_ts, dt, stime), _key
    | where t_sum > 0 and _ts <= etime
    | extend tw_avg = tw_sum/t_sum
    | project-away tw_sum, t_sum
    | order by _key asc, _ts asc 
};
// Write your query to use the function here.

Beispiel

Im folgenden Beispiel wird der Aufrufoperator verwendet, um die Funktion auszuführen.

Um eine abfragedefinierte Funktion zu verwenden, rufen Sie sie nach der definition der eingebetteten Funktion auf.

let time_weighted_avg2_fl=(tbl:(*), t_col:string, y_col:string, key_col:string, stime:datetime, etime:datetime, dt:timespan)
{
    let tbl_ex = tbl | extend _ts = column_ifexists(t_col, datetime(null)), _val = column_ifexists(y_col, 0.0), _key = column_ifexists(key_col, '');
    let _etime = etime + dt;
    let gridTimes = range _ts from stime to _etime step dt | extend _val=real(null), dummy=1;
    let keys = materialize(tbl_ex | summarize by _key | extend dummy=1);
    gridTimes
    | join kind=fullouter keys on dummy
    | project-away dummy, dummy1
    | union tbl_ex
    | where _ts between (stime.._etime)
    | partition hint.strategy=native by _key (
      order by _ts desc, _val nulls last
    | scan declare(val1:real=0.0, t1:datetime) with (                // fill backward null values
        step s: true => val1=iff(isnull(_val), s.val1, _val), t1=iff(isnull(_val), s.t1, _ts);)
    | extend dt1=(t1-_ts)/1m
    | order by _ts asc, _val nulls last
    | scan declare(val0:real=0.0, t0:datetime) with (                // fill forward null values
        step s: true => val0=iff(isnull(_val), s.val0, _val), t0=iff(isnull(_val), s.t0, _ts);)
    | extend dt0=(_ts-t0)/1m
    | extend _twa_val=iff(dt0+dt1 == 0, _val, ((val0*dt1)+(val1*dt0))/(dt0+dt1))
    | scan with (                                                    // fill forward null twa values
        step s: true => _twa_val=iff(isnull(_twa_val), s._twa_val, _twa_val);)
    | extend diff_t=(next(_ts)-_ts)/1m
    )
    | where isnotnull(diff_t)
    | order by _key asc, _ts asc
    | extend next_twa_val=iff(_key == next(_key), next(_twa_val), _twa_val)
    | summarize tw_sum=sum((_twa_val+next_twa_val)*diff_t/2.0), t_sum =sum(diff_t) by bin_at(_ts, dt, stime), _key
    | where t_sum > 0 and _ts <= etime
    | extend tw_avg = tw_sum/t_sum
    | project-away tw_sum, t_sum
    | order by _key asc, _ts asc 
};
let tbl = datatable(ts:datetime,  val:real, key:string) [
    datetime(2021-04-26 00:00), 100, 'Device1',
    datetime(2021-04-26 00:45), 300, 'Device1',
    datetime(2021-04-26 01:15), 200, 'Device1',
    datetime(2021-04-26 00:00), 600, 'Device2',
    datetime(2021-04-26 00:30), 400, 'Device2',
    datetime(2021-04-26 01:30), 500, 'Device2',
    datetime(2021-04-26 01:45), 300, 'Device2'
];
let minmax=materialize(tbl | summarize mint=min(ts), maxt=max(ts));
let stime=toscalar(minmax | project mint);
let etime=toscalar(minmax | project maxt);
let dt = 1h;
tbl
| invoke time_weighted_avg2_fl('ts', 'val', 'key', stime, etime, dt)
| project-rename val = tw_avg
| order by _key asc, _ts asc

Output

_ts _Schlüssel val
2021-04-26 00:00:00.0000000 Device1 218,75
2021-04-26 01:00:00.0000000 Device1 206.25
2021-04-26 00:00:00.0000000 Device2 462.5
2021-04-26 01:00:00.0000000 Device2 412.5

Der erste Wert von Device1 lautet (45m*(100+300)/2 + 15m*(300+250)/2)/60m = 218,75, der zweite Wert ist (15m*(250+200)/2 + 45m*200)/60m = 206,25.
Der erste Wert von Device2 ist (30m*(600+400)/2 + 30m*(400+450)/2)/60m = 462,5, der zweite Wert ist (30m*(450+500)/2 + 15m*(500+300)/2 + 15m*300)/60m = 412,5.