2015-10-22 2 views
2

Я понимаю, что есть много ответов, говорящих о том, как вычислять процентили с использованием LINQ, но я не нашел подходящего ответа для моей проблемы.Вычисление процентиля с использованием LINQ в C#

У меня есть список объектов, который содержит продолжительность времени как одно из свойств, на котором я должен вычислить процентиль, группируя список по имени. Есть ли простой способ сделать это, используя linq в C#. Мой объект выглядит, как показано ниже:

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

Какие ответы вы нашли и почему они не применяются к вашему вопросу? Кроме того, чтобы уточнить, вы имеете в виду [percentile] (https://en.wikipedia.org/wiki/Percentile), правильно? –

+0

Какой [процентиль] (https://en.wikipedia.org/wiki/Percentile) вы хотите? – DineMartine

ответ

0

Это будет построить словарь, который отображает экземпляры 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); 
+1

Разве это не дает процент, а не процентиль? –

+0

Хм, это правда, я предполагал, что процент имел в виду. Я рассмотрю его – kai

2
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 
    }); 
Смежные вопросы