time_weighted_avg2_fl()
Gilt für: ✅Microsoft Fabric✅Azure Data Explorer✅Azure Monitor✅Microsoft 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.