如何计算百分位数?

Posted

技术标签:

【中文标题】如何计算百分位数?【英文标题】:How to calculate the percentile? 【发布时间】:2013-08-31 07:55:20 【问题描述】:

我有如下访问日志存储在 mongodb 实例中:

Time                           Service                      Latency
[27/08/2013:11:19:22 +0000]    "POST Service A HTTP/1.1"    403
[27/08/2013:11:19:24 +0000]    "POST Service B HTTP/1.1"    1022 
[27/08/2013:11:22:10 +0000]    "POST Service A HTTP/1.1"    455 

Oracle 中是否有类似PERCENTILE_DISC 的分析函数来计算百分位数?

我想计算一段时间内的延迟百分位数。

【问题讨论】:

【参考方案1】:

似乎仍然没有计算百分位数的本地方法,但通过组合几个聚合运算符,您可以获得相同的结果。

db.items.aggregate([
        '$group': 
            '_id': 
                'league': '$league',
                'base': '$base',
                'type': '$type'
            ,
            'value': '$push': '$chaosequiv'
        ,
        '$unwind': '$value',
        '$sort': 'value': 1,
        '$group': '_id': '$_id', 'value': '$push': '$value',
        '$project': 
            '_id': 1,
            'value': '$arrayElemAt': ['$value', '$floor': '$multiply': [0.25, '$size': '$value']]
        
    ], allowDiskUse=True)

请注意,我在 pymongo 中编写了我的原始代码,以解决需要对第一组中的 3 个字段进行分组的问题,因此这可能比单个字段所需的更复杂。我会针对这个问题写一个解决方案,但我认为没有足够的具体信息。

【讨论】:

我知道流放之路交易工具的代码,当我看到它时。 :) 先排序再分组不行吗?而不是分组、展开、排序、再次分组。【参考方案2】:

Mongo 4.4 开始,$group 阶段有一个新的聚合运算符 $accumulator,允许通过 javascript 用户定义的函数在文档分组时自定义累积文档。

因此,为了找到第 20 个百分位数:

//  "a" : 25, "b" : 12 
//  "a" : 89, "b" : 73 
//  "a" : 25, "b" : 7  
//  "a" : 25, "b" : 17 
//  "a" : 89, "b" : 14 
//  "a" : 89, "b" : 17 
//  "a" : 25, "b" : 24 
//  "a" : 25, "b" : 15 
//  "a" : 25, "b" : 22 
//  "a" : 25, "b" : 94 
db.collection.aggregate([
   $group: 
    _id: "$a",
    percentile: 
      $accumulator: 
        accumulateArgs: ["$b"],
        init: function()  return []; ,
        accumulate: function(bs, b)  return bs.concat(b); ,
        merge: function(bs1, bs2)  return bs1.concat(bs2); ,
        finalize: function(bs) 
          bs.sort(function(a, b)  return a - b );
          return bs[Math.floor(bs.length*.2) + 1];
        ,
        lang: "js"
      
    
  
])
//  "_id" : 89, "percentile" : 17 
//  "_id" : 25, "percentile" : 15 

累加器:

在场上积累b (accumulateArgs) 初始化为空数组 (init) 在数组中累积b 项(accumulatemerge) 最后对b项目(finalize)执行百分位数计算

【讨论】:

【参考方案3】:

计算从 0 到 100 的百分位数(第 5 步)

//  "session": 1, "date" : 2013-08-27 11:00::00, "latency" : 403 
//  "session": 1, "date" : 2013-08-27 11:00::01, "latency" : 1022 
//  "session": 1, "date" : 2013-08-27 11:00::02, "latency" : 455 
//  "session": 1, "date" : 2013-08-27 11:00::02, "latency" : 307 
//  "session": 2, "date" : 2013-08-27 12:00::00, "latency" : 403 
//  "session": 2, "date" : 2013-08-27 12:00::01, "latency" : 1022 
//  "session": 2, "date" : 2013-08-27 12:00::02, "latency" : 455 
//  "session": 2, "date" : 2013-08-27 12:00::02, "latency" : 307 

var interval = 5

db.getCollection.aggregate([
    
        $group:
            _id:  $toString: "$session" ,
            value:  $push: "$atency" 
        
    ,
    
        $addFields:
            index : $range: [0, 100, interval]
        
    ,
    $unwind: "$index",
    
        $addFields:
            p_index : $divide: ["$index", 100]
        
    ,
    
        $addFields:
            percentile_x : $toDouble: '$arrayElemAt': ['$value', '$floor': '$multiply': ["$p_index", '$size': '$value']]
        
    ,
       $project: 
           'percentile': "$index",
           'value': "$percentile_x"
        
    ,
        $sort: 
          percentile: 1
        
    
])

【讨论】:

以上是关于如何计算百分位数?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JavaScript(或 PHP)中获取数组的中位数和四分位数/百分位数?

Pandas .. 分位数函数是不是需要排序数据来计算百分位数?

R语言分位数计算Percentiles

在 SQL 中分析并形成分位数并计算落在各个分位数中的值的百分比

JavaScript中的分位数/百分点/百分位数/逆累积分布函数

如何计算列的每个值所在的百分位数? (Spark SQL)[重复]