Freigeben über


time_weighted_avg_fl()

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

Die Funktion time_weighted_avg_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 füllt den Wert aus dem aktuellen Beispiel bis zum nächsten aus. Alternativ time_weighted_avg2_fl() interpoliert linear den Metrikwert zwischen aufeinander folgenden Beispielen.

Syntax

T | invoke time_weighted_avg_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_avg_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 asc, _val nulls last
        | scan declare(f_value:real=0.0) with (step s: true => f_value = iff(isnull(_val), s.f_value, _val);) // fill forward null values
        | extend diff_t=(next(_ts)-_ts)/1m
    )
    | where isnotnull(diff_t)
    | summarize tw_sum=sum(f_value*diff_t), 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
};
// 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_avg_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 asc, _val nulls last
        | scan declare(f_value:real=0.0) with (step s: true => f_value = iff(isnull(_val), s.f_value, _val);) // fill forward null values
        | extend diff_t=(next(_ts)-_ts)/1m
    )
    | where isnotnull(diff_t)
    | summarize tw_sum=sum(f_value*diff_t), 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
};
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_avg_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 150
2021-04-26 01:00:00.0000000 Device1 225
2021-04-26 00:00:00.0000000 Device2 500
2021-04-26 01:00:00.0000000 Device2 400

Der erste Wert von Device1 lautet (45m*100 + 15m*300)/60m = 150, der zweite Wert ist (15m* 300 + 45m*200)/60m = 225.
Der erste Wert von Device2 lautet (30m*600 + 30m*400)/60m = 500, der zweite Wert ist (30m* 400 + 15m* 500 + 15m*300)/60m = 400.