Partilhar via


time_weighted_avg_fl()

Aplica-se a: ✅Microsoft FabricAzure Data Explorer✅Azure MonitorMicrosoft Sentinel

A função time_weighted_avg_fl() é uma UDF (função definida pelo usuário) que calcula a média ponderada de tempo de uma métrica em uma determinada janela de tempo, em compartimentos de tempo de entrada. Essa função é semelhante ao operador summarize. A função agrega a métrica por compartimentos de tempo, mas em vez de calcular avg() simples do valor da métrica em cada compartimento, ela pondera cada valor por sua duração. A duração é definida a partir do carimbo de data/hora do valor atual até o carimbo de data/hora do próximo valor.

Existem duas opções para calcular a média ponderada pelo tempo. Essa função preenche o valor da amostra atual até a próxima. Como alternativa , time_weighted_avg2_fl() interpola linearmente o valor da métrica entre amostras consecutivas.

Sintaxe

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

Saiba mais sobre as convenções de sintaxe.

Parâmetros

Nome Digitar Obrigatória Descrição
t_col string ✔️ O nome da coluna que contém o carimbo de data/hora dos registros.
y_col string ✔️ O nome da coluna que contém o valor da métrica dos registros.
key_col string ✔️ O nome da coluna que contém a chave de partição dos registros.
Stime datetime ✔️ A hora de início da janela de agregação.
tempo datetime ✔️ A hora de término da janela de agregação.
dt timespan ✔️ O compartimento de tempo de agregação.

Definição de função

Você pode definir a função inserindo seu código como uma função definida por consulta ou criando-a como uma função armazenada em seu banco de dados, da seguinte maneira:

Defina a função usando a instrução let a seguir. Nenhuma permissão é necessária.

Importante

Uma instrução let não pode ser executada sozinha. Ele deve ser seguido por uma instrução de expressão tabular. Para executar um exemplo funcional de time_weighted_avg_fl(), consulte Exemplo.

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.

Exemplo

O exemplo a seguir usa o operador invoke para executar a função.

Para usar uma função definida por consulta, invoque-a após a definição da função inserida.

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

Saída

_ts _chave 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

O primeiro valor de Device1 é (45m*100 + 15m*300)/60m = 150, o segundo valor é (15m*300 + 45m*200)/60m = 225.
O primeiro valor de Device2 é (30m*600 + 30m*400)/60m = 500, o segundo valor é (30m*400 + 15m*500 + 15m*300)/60m = 400.