Стандартное отклонение в LINQ
LINQ, которая делает модели в статистической функции SQL STDDEV()
(стандартное отклонение)?
Если нет, то каков самый простой / наилучший способ его расчета?
пример:
SELECT test_id, AVERAGE(result) avg, STDDEV(result) std
FROM tests
GROUP BY test_id
5 ответов:
Вы можете сделать свой собственный расширением расчета
public static class Extensions { public static double StdDev(this IEnumerable<double> values) { double ret = 0; int count = values.Count(); if (count > 1) { //Compute the Average double avg = values.Average(); //Perform the Sum of (value-avg)^2 double sum = values.Sum(d => (d - avg) * (d - avg)); //Put it all together ret = Math.Sqrt(sum / count); } return ret; } }
Если у вас пример населения, а не всего населения, то вы должны использовать
ret = Math.Sqrt(sum / (count - 1));
.преобразовать в расширение от добавление стандартного отклонения в LINQ от Chris Bennett.
ответ Dynami работает, но делает несколько проходов через данные, чтобы получить результат. Это однопроходный метод, который вычисляет выборочное стандартное отклонение:
public static double StdDev(this IEnumerable<double> values) { // ref: http://warrenseen.com/blog/2006/03/13/how-to-calculate-standard-deviation/ double mean = 0.0; double sum = 0.0; double stdDev = 0.0; int n = 0; foreach (double val in values) { n++; double delta = val - mean; mean += delta / n; sum += delta * (val - mean); } if (1 < n) stdDev = Math.Sqrt(sum / (n - 1)); return stdDev; }
это выборочное стандартное отклонение так как он делится на
n - 1
. Для нормального стандартного отклонения вам нужно разделить наn
вместо.использует метод Уэлфорда который имеет более высокую точность по сравнению с
Average(x^2)-Average(x)^2
метод.
это преобразует ответ Дэвида Кларка в расширение, которое следует той же форме, что и другие агрегатные функции LINQ, такие как Average.
загрузка может быть:
var stdev = data.StdDev(o => o.number)
public static class Extensions { public static double StdDev<T>(this IEnumerable<T> list, Func<T, double> values) { // ref: https://stackoverflow.com/questions/2253874/linq-equivalent-for-standard-deviation // ref: http://warrenseen.com/blog/2006/03/13/how-to-calculate-standard-deviation/ var mean = 0.0; var sum = 0.0; var stdDev = 0.0; var n = 0; foreach (var value in list.Select(values)) { n++; var delta = value - mean; mean += delta / n; sum += delta * (value - mean); } if (1 < n) stdDev = Math.Sqrt(sum / (n - 1)); return stdDev; } }
public static double StdDev(this IEnumerable<int> values, bool as_sample = false) { var count = values.Count(); if (count > 0) // check for divide by zero // Get the mean. double mean = values.Sum() / count; // Get the sum of the squares of the differences // between the values and the mean. var squares_query = from int value in values select (value - mean) * (value - mean); double sum_of_squares = squares_query.Sum(); return Math.Sqrt(sum_of_squares / (count - (as_sample ? 1 : 0))) }