time_weighted_avg_fl()

関数 time_weighted_avg_fl() は、指定された時間枠内のメトリックの時間加重平均を入力タイム ビンに対して計算する ユーザー定義関数 (UDF) です。この関数は summarize 演算子に似ています。 この関数ではタイム ビン別にメトリックを集計しますが、各ビンでメトリックの単純 avg() を計算する代わりに、その継続時間で各値を重み付けします。 継続時間は、現在の値のタイムスタンプから次の値のタイムスタンプまでと定義されます。

この種類の集計は、メトリック値が変化した場合にのみ出力される (一定の間隔ではない) ユース ケースに必要です。 たとえば、エッジ デバイスが変更時にのみメトリックをクラウドに送信する IoT で通信帯域幅を最適化するような場合です。

構文

T | invoke time_weighted_avg_fl(t_coly_colkey_colstimeetimedt)

構文規則について詳しく知る。

パラメーター

名前 必須 説明
t_col string ✔️ レコードのタイム スタンプを含む列の名前。
y_col string ✔️ レコードのメトリック値を含む列の名前。
key_col string ✔️ レコードのパーティション キーを含む列の名前。
stime datetime ✔️ 集計ウィンドウの開始時刻。
etime datetime ✔️ 集計ウィンドウの終了時刻。
dt timespan ✔️ 集計時間ビン。

関数の定義

関数を定義するには、次のように、コードをクエリ定義関数として埋め込むか、データベースに格納されている関数として作成します。

次の let ステートメントを使用して関数を定義します。 権限は必要ありません。

重要

let ステートメントは単独では実行できません。 その後に 表形式の式ステートメントを記述する必要があります。 の動作例を実行するには、「time_weighted_avg_fl()」を参照してください。

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 timestamp = column_ifexists(t_col, datetime(null)), value = column_ifexists(y_col, 0.0), key = column_ifexists(key_col, '');
    let gridTimes = range timestamp from stime to etime step dt | extend value=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 timestamp between (stime..etime)
    | partition hint.strategy=native by key (
        order by timestamp asc, value nulls last
        | scan declare(f_value:real=0.0) with (step s: true => f_value = iff(isnull(value), s.f_value, value);)    // fill forward null values
        | extend diff_t=(next(timestamp)-timestamp)/1m
    )
    | where isnotnull(diff_t)
    | summarize tw_sum=sum(f_value*diff_t), t_sum =sum(diff_t) by bin_at(timestamp, dt, stime), key
    | where t_sum > 0
    | extend tw_avg = tw_sum/t_sum
    | project-away tw_sum, t_sum
};
// Write your query to use the function here.

次の例では、 invoke 演算子 を使用して関数を実行します。

クエリ定義関数を使用するには、埋め込み関数定義の後にそれを呼び出します。

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 timestamp = column_ifexists(t_col, datetime(null)), value = column_ifexists(y_col, 0.0), key = column_ifexists(key_col, '');
    let gridTimes = range timestamp from stime to etime step dt | extend value=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 timestamp between (stime..etime)
    | partition hint.strategy=native by key (
        order by timestamp asc, value nulls last
        | scan declare(f_value:real=0.0) with (step s: true => f_value = iff(isnull(value), s.f_value, value);)    // fill forward null values
        | extend diff_t=(next(timestamp)-timestamp)/1m
    )
    | where isnotnull(diff_t)
    | summarize tw_sum=sum(f_value*diff_t), t_sum =sum(diff_t) by bin_at(timestamp, dt, stime), key
    | where t_sum > 0
    | 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), 200, 'Device1',
    datetime(2021-04-26 01:06), 100, 'Device1',
    datetime(2021-04-26 00:30), 400, 'Device2',
    datetime(2021-04-26 01:00), 100, 'Device2',
    datetime(2021-04-26 02:00), 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, timestamp asc

出力

timestamp key val
2021-04-26 00:00:00.0000000 Device1 125
2021-04-26 01:00:00.0000000 Device1 110
2021-04-26 00:00:00.0000000 Device2 200
2021-04-26 01:00:00.0000000 Device2 100

最初の値は (45m*100 + 15m*200)/60m = 125 で、2 つ目の値は (6m200 + 54m100)/60m = 110 です。以下、同様に続きます。