You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用hll()与tdigest()确保全局与日度分层分位数结果一致?

KQL分位数计算一致性问题及hll/tdigest正确用法

需求说明

需要完成三类分位数计算,核心要求是基于日度预计算的分布信息再聚合得到的全局分位数,与直接计算的全局分位数结果完全一致:

  • 直接计算全日期范围的全局分位数
  • 按日期维度计算每日的分布摘要信息
  • 基于每日的分布摘要聚合,计算全局分位数,结果需与第一种方式一致

当前问题

直接先计算日度中位数,再对这些中位数求全局中位数,结果与直接全局分位数差异明显(示例中直接全局中位数为40,二次计算的中位数为35)。这是因为仅保留日度中位数丢失了原始数据的分布细节,无法还原全局完整分布。

正确解决方案:使用tdigest()合并分布信息

tdigest()是KQL中用于存储数值分布的近似数据结构,支持合并操作——可以先按日度生成每个分组的tdigest,再合并所有tdigest得到全局分布,最后计算分位数,结果与直接全局计算一致。

示例代码:基于tdigest实现一致性分位数计算

let MySourceTable = datatable(col1:int, col2:int, Value:int, EventUTCDateTime:datetime)
[
1,2,10,'2022-01-01 01:00:01',
1,2,20,'2022-01-01 02:01:01',
1,2,15,'2022-01-02 03:05:01',
1,2,40,'2022-01-03 01:30:01',
1,2,20,'2022-01-03 02:30:01',
1,2,50,'2022-01-04 07:30:01',
1,2,70,'2022-01-05 06:30:01',
1,2,45,'2022-01-05 07:30:01',
1,2,90,'2022-01-05 07:30:01',
1,2,40,'2022-01-06 07:30:01'
];

-- 1. 直接计算全局中位数
MySourceTable
| summarize GlobalMedian = percentile(Value, 50)

-- 2. 按日生成tdigest,再合并计算全局中位数(结果与上面一致)
MySourceTable
| extend EventUTCDate = bin(EventUTCDateTime, 1d)
| summarize daily_dist = tdigest(Value) by col1, col2, EventUTCDate
| summarize global_dist = merge_tdigests(daily_dist)
| summarize GlobalMedian_FromDailyTDigest = percentile_tdigest(global_dist, 50)

代码说明

  1. tdigest(Value):为每日的Value列生成压缩的分布摘要,保留分位数计算所需的核心信息
  2. merge_tdigests(daily_dist):将所有日度的tdigest合并为一个全局分布摘要
  3. percentile_tdigest(global_dist, 50):基于合并后的全局tdigest计算中位数,结果与直接全局计算完全一致

hll()的适用场景说明

hll()是用于基数估计(统计唯一值数量)的近似数据结构,不适合分位数计算。如果你的场景涉及唯一值计数的分层聚合,可以用hll()+dcount_hll(),但分位数场景必须使用tdigest()系列函数。

内容的提问来源于stack exchange,提问作者Brahmaiah Takkellapati

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 21:53:10