在c#中使用LINQ计算百分位数

本文关键字:百分 计算 LINQ | 更新日期: 2023-09-27 18:18:45

我知道有很多答案说如何使用LINQ计算百分位数,但我找不到任何相关的答案。

我有一个对象列表,其中包含时间持续时间作为属性之一,我必须通过按名称分组列表来计算百分位数。在c#中使用linq是否有最简单的方法来做到这一点?我的对象如下所示:

class Performance{
        public string Name { get; set; }
        public Nullable<decimal> DurationMilliSeconds { get; set; }
        public string typeName { get; set; }
}

在c#中使用LINQ计算百分位数

Random r = new Random();
int performers = 500;
var performances = Enumerable.Range(1, performers)
  .Select(e => new Performance { Name="P"+e, DurationMilliSeconds=r.Next(5000)});
var pCount = performances.Count();
var percentiles = performances
  .OrderBy(p => p.DurationMilliSeconds)
  .Select((p, i) => new { p, i=i+1 })
  .Select(p => new {
    Name = p.p.Name,
    Duration = p.p.DurationMilliSeconds,
    Percentile = p.i / (decimal)pCount
  });

这将构造一个字典,该字典将按名称分组的Performance实例映射为该组的DurationMilliSeconds属性与集合中所有Performance对象的总持续时间的总和的百分比。假设null持续时间为0。

var performances = Enumerable.Empty<Performance>();
var totalDuration = performances.Sum(p => p.DurationMilliSeconds ?? 0M);
var durationPercentages = performances
    .GroupBy(p => p.Name)
    .ToDictionary(
        group => group.Key,
        group => group.Sum(p => (p.DurationMilliSeconds ?? 0M))/totalDuration);